《小雪》
唐·戴叔伦
花雪随风不厌看,更多还肯失林峦。
愁人正在书窗下,一片飞来一片寒。*
纪述昨天服务宕机的点点滴滴,以及面对问题该如何解决?为什么会发生?以及如何避免错误?
阳光明媚的午后,午睡之后,慢慢的伸展懒腰,一切都是那么洋溢自得,又开开心心开启了下午的工作,本来像今天阳光一样温暖这冬天的寒冷,忽如一夜东风来,千树万树花未开,跑了五六个小时的服务之后,公司断网了,然后噩梦的开始,服务白跑了,线上数据并没有生成,也就是说,这几个小时的工作白费了,当时浑身一机灵,赶紧想其他办法,这个办法已经堵死了,时间短,任务重,看看还有没有其他办法冲破牢笼?
故事就这样悄无声息发生着?
为了赶紧启动第二套方案,把从昨天半夜到今天耗费了差不多十个小时的服务认真思考了一番,是不是可以转化为脚本,这样数据量大的话也很容易插入到数据库,经过一番论证之后,想法是可行的,然后在下午五点的时候,启动了脚本也为后来隐患埋下了雷…
在五点脚本跑完之后,几万条数据插入数据库中就开启了这段旅程,惊险刺激,变幻莫测?
五点一刻,服务器发生了宕机,用户开始反馈,服务器没有反应了,然后我们工作人员就开始登录用户端,视频,测评,登录界面没有了反应,呼吸停止,程序员这个时候就像医生开始抢救病人,开始了学术上的实践和论证,有经验的架构师、工程师出动,像是打一场必胜的战争,有手拿火箭筒的、有拿手榴弹的,也有像我手拿小米加步枪的,脑子充斥着,临阵磨钱,不利也光,我脑子这个时候就拿起了小米加步枪,冲到了前线,不管三七二十一,一顿突突,伤敌一千,自损八百,就与敌人厮杀了起来…
五点半之内:也就是半个小时前前后后启动了好几次,然后CPU就飙升99%?
这个时候心情就像是过山车,惊险刺激,好想捉到一根救命的稻草,CPU飙升?
猜想一: 消息队列?定时任务过大?
然后从这两点出发,论证自己的观点,然后在项目中把消息队列先注销(屏蔽掉),再次启动项目,也不行,然后看看四五点中定时任务执行站内信,查询了一下数据库,也没有那么大… 死路
猜想二:websocket通信?
开始下载日志,分析日志,日志是程序员留下来的最宝贵的财富,有个熟悉又陌生的次出现,stream is closed?
顺着这个顺序进行查找,先把通信关闭了,然而并没有解决…
猜想三: 服务器状态,性能,出入网流量?
然后监听服务器,发现出入网流量居高不下,怀疑是不是收到黑客攻击,赶紧让运维在五点四十到五十重新启动到时间到服务器宕机的黄金十分钟,抓取了这十分钟的接口日志,然后看没有什么异常,也没发现特殊的接口(并没有发现敌人,看不出异常),抽样详细看了几条接口服务及数据,没有发现异常
此时已经头皮发麻,脑子不清醒了,该如何是好?此时已经不像刚开始的心情一样了,脑子已经精疲力尽不知如何是好,但是信心还是很坚决的,但是不知该如何出手了。
最后挣扎了一下,然后就稍微让大脑休息一下,开始回忆,到底我们做了什么,服务就宕机了,突然,灵机一动,就跑了一个脚本,然后就服务器就崩溃了吗?觉得有点不可思议,然后就试着把生成了一张表数据清空了,然后服务器恢复了,此时已经经历了两个多小时,开始分析,这张对这张表做了什么,分析出,用户必须会访问的界面,这个接口会用到这个接口,然后,看到了for循环下,四个查询,一个list列表下4*40次查询,然后计算耗时,cpu飙升,对后宕机,原因找出来了,之前没有测试出来对原因也赶巧,如果为空对原因,就不走这逻辑了,处理老数据造成对原因,多么痛对领悟啊,看到最后的结果,心都碎了,团队人员增多的时候,代码审核是多么重要的。。。。。。
此时已经过去了紧张的两个多小时(服务器停止以后,显示一个停机维护页面,再者可以搞一个备用的服务器地址,如果主服务挂了,切换到另一台备用地址,再坏的情况下,都要维护军心,服务器可以挂,军心不可散,公关部发一些告示维护用户)
TIPS:以下是这次学习所用到的知识点以及一些blog资料还是不错
cpu飙升:程序计算会造成cpu飙升
案例一:
生产环境凌晨突然宕机,日志报错数据库链接超时
cpu、内存 磁盘 飙升
系统采用了springcloud 架构,通过阿里云的监控对比,发现仅仅一台服务器的宕机
分析日志发现,宕机的机器,凌晨接发大量请求,10分钟后宕机
初步怀疑负载均衡失效,进一步分析,流量集中在inner 接口,应该是FeignClient 请求
同时日志中出现sql 批量操作,进一步确定是Eurake 负载失效或者项目内部代码逻辑问题。
排查定时任务,确定逻辑,凌晨的定时任务在派发卡券的时候使用了多线程导致服务器宕机,
派发卡券是运营模块发起,定时任务通过HTTP直链触发,形成了一个节点正常,一个节点宕机的情况。
代码逻辑中使用了多线程,并且频繁操作数据库,导致了程序运行一段时间之后,整个运营模块宕机。
排查难点:宕机时,服务器日志丢失,MySQL数据库 链接不足导致服务器宕机,而导致链接不足的逻辑代码较难定位。
定时任务设计不合理,批量处理程序设计不合理。
生产环境中 往往没有直接登录服务器权限,一般思路从代码逻辑入手,毕竟MySQL Linux 或者spring cloud 都是经过时间检验的,服务器宕机更有可能是自己写的代码逻辑有问题。
案例二: 服务器崩溃的常见原因及分析一
服务器宕机可以分为两种:假死机和死机
假死机(非蓝屏死机)是由于硬件资源暂时性地被消耗殆尽,因而无法对外部指令进行响应的现象, 通常是网站处于访问高峰期,带宽等资源跑满,这时只需要等待一定的时间,待服务器腾出更多的硬件资源即可恢复正常,
而死机,如果通过ping测试服务器,键盘切换数字锁定键(NumLock)或大写锁定键(Caps Lock)功能, 显示器无画面输出,或者鼠标光标没有任何反应则表明服务器硬件故障
服务器出现宕机的常见原因
1.在运行环境的问题中,最普遍的问题时磁盘空间耗尽。
2…在性能问题中,最普通的服务器宕机原因确实是运行很糟糕的SQL, 但也不一定都是这个原因,比如也有很多问题时由于服务器Bug或错误的行为导致的。
3…糟糕的Schema和索引设计是第二大影响性能的问题。
4…复制问题通常由于主备数据不一致导致。
5.数据丢失问题通常由于drop table的错误操作导致,并总是便随着缺少可用备份的问题。
如何查看服务器宕机的原因
a、是否是应用程序导致内存溢出或者泄露,out of memory导致
b、是否是进程过多或者不断创建,耗尽资源导致
c、是否是数据库程序死锁,连接数过多导致
d、是否是应用程序异常导致
e、是否是流量负载过大导致
f、 是否是遭受黑客入侵攻击导致
g、是否是误操作导致
服务器出现宕机该如何解决
a.要即时发现服务器宕机的问题。时间就是金钱,这是不变的真理。我们要第一时间, 发现宕机的问题。如果他服务器宕机时,为了避免造成不必要的损失,要尽早通知服务商解决相关问题。
b.最好准备2个网站空间,他们存放的内容相同,而ip不同,并且机房的地理位置不同。这样2个主机, 同时宕机的可能性就大大降低了。第一时间发现宕机问题后,可以迅速的通过修改dnspod.com中的域名记录,指向目前正常的网站空间。Dnspod解析生效的时间是实时的, 而一般的dns服务器,刷新时间较长,对外声称24小时内生效,按照实际经验看来,差不多30分钟内生效,否则就要检查域名绑定是否正确了。
案例三: 服务器崩溃的常见原因及分析二
在计算机网络日益普及的今天,计算机安全不但要求防治计算机病毒,而且要提高系统抵抗黑客非法入侵的能力,还要提高对远程数据传输的保密性,避免在传输途中遭受非法窃取。
第一,内存泄漏
当内存是在子程序中被分 配时,通常会出现这种问题,其结果是程序从子程序中返回时不会释放内存。如此一来,对已分配的内存的引用就会丢失,只要操作系统还在运行中,则进程就会一 直使用该内存。
第二,C指针错误
用C或C++编写的程序,如Web服务器API模块,有可能导致系统的崩溃,因为只要间接引 用指针中出现一个错误,就会导致操作系统终止所有程序。另外,使用了糟糕的C指针的Java模拟量将访问一个空的对象引用。
第三,数据库中的临时表不够用
许多数据库的临时表数目都是固定的,临时表即保留查询结果的内存区域。在临时表中的数据都被读取后,临时表便会被释放,但大量同时进行的查询可能耗尽数目固定的所有临时表。这时,其他的查询就需要列队等候,直到有临时表被释放时才能再继续运行。
第四,线程死锁
由多线程带来的性能改善是以可靠性为代价的,主要是因为这样有可能产生线程死锁。线程死锁时,第一个线程等待第二个线程释放资源,而同时第二个线程又在等待第一个线程释放资源。
第五,磁盘已满
导致系统无法正常运行的最可能的原因是磁盘已满。一个好的网络管理员会密切关注磁盘的使用情况,隔一定的时间,就需要将磁盘上的一些负载转存到备份存储介质中。
第六,服务器超载
Netscape Web服务器的每个连接都使用一个线程。Netscape Enterprise Web服务器会在线程用完后挂起,而不为已存在的连接提供任何服务。
案例四: cpu飙升,排查经历
一个合作公司,项目是使用nginx和两台tomcat负载,其中一台服务器cpu飙升,然后导致部分用户访问页面很卡,超时,甚至500。
解决经历:
将nginx配置文件更改,取下来那台cpu很高的服务器。用户这时可以正常使用,现在专心排查问题。
使用ps -ef | grep java 命令得到java进程号,
然后使用top -H -p java进程号 命令得到当前进程使用cpu较高的线程。(因为现在已经解决了问题,所以截图的cpu使用率不高)
记下使用cpu使用比较高的线程id(PID),
执行 jstack java进程号 >> 文件名.txt ,将进程线程使用情况输出到文件内
- 把记下的线程id转成16进制,去线程堆栈里面找,可以看到当前线程在干嘛。
然后在继续排查,具体原因是因为什么。当时我遇见的情况是gc一直再执行,而且内存也超了。一步步排查,确定是转化文档出问题,一个excel文档内有上百万空表格。对他进行了一个限制。然后就没再出过问题。
https://blog.csdn.net/hyc123123123123/article/details/79556183
https://blog.csdn.net/keep_learn/article/details/82916540
https://blog.csdn.net/weixin_41755830/article/details/80519715
https://blog.csdn.net/Beyond_2016/article/details/81478368
以上是自己一些心得,以免以后犯同样的错误,以及一些对我有帮助的blog,或许也会对看到这篇文章的人同样🈶️帮助,