平稳运行半年的系统宕机了,记录一次排错调优的全过程!

简介: 最近发生了一件很让人头疼的事情,已经上线半年且平稳运行半年系统在年后早高峰的使用时发生了濒临宕机的情况。访问速度特别慢,后台查到大量time_wait的连接,从代码层面到架构层面到网络层面排查了几天几夜,总算是有了结果。

听说微信搜索《Java鱼仔》会变更强哦!


本文收录于JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看哦


(一)前言


最近发生了一件很让人头疼的事情,已经上线半年且平稳运行半年系统在年后早高峰的使用时发生了濒临宕机的情况。访问速度特别慢,后台查到大量time_wait的连接,从代码层面到架构层面到网络层面排查了几天几夜,总算是有了结果。


(二)架构、问题描述


先简单描述一下这个系统的架构,公网域名对应的公网IP连接着华为云的ELB弹性负载均衡服务,ELB下是两台Nginx服务器多活,Nginx下连接着四台内网应用集群服务器(通过专线),Mysql服务器读写分离、Redis服务器主从配置。


发生宕机问题时,四台集群服务器的Load Average飙到了200,要知道8核的服务器Load average超过40就需要注意了。同时Nginx的tcp连接数也异常,有大量的TIME_WAIT连接。


网络异常,图片无法展示
|


(三)问题排查


这个问题主要原因还是系统挡不住突然间的高并发,根据上面的这些报错数据,首先是想办法把load average降下去。请求大于当前的处理能力,会出现等待,引起load average升高。因此主要从下面几个方面进行了排查:


3.1 检查Nginx配置


首先是运维人员检查Nginx配置,看看是否是配置不对造成大量time_wait连接,检查结果是没有问题。


3.2 抓网络请求


运维人员帮忙抓取了应用服务器在高并发时的网络包,最后分析下来有一个接口的请求次数是所有请求的40%。这是一个疑问点,这个请求为什么会被调用如此多的次数。


3.3 检查线程堆栈信息


因为请求数量如此多,因此需要检查占用CPU最高的线程堆栈信息,最后发现垃圾回收线程竟然占用了30%+资源,说明垃圾回收应该是存在一些问题的。


网络异常,图片无法展示
|


3.4 检查数据库连接池


检查数据库连接池是否正常,看看有无死锁或者资源耗尽等问题,查出来是一切正常的。


3.5 检查垃圾回收情况


通过jstat -gcutil 命令抓取垃圾回收情况,发现YGC很频繁,大概一秒一次,下图是高峰期过了之后的垃圾回收情况,YGC大概在一分钟8次左右。因此也是怀疑业务代码存在问题。


网络异常,图片无法展示
|


(四)定位业务代码


通过上面的信息,我们初步怀疑那个被频繁调用的接口存在问题。查到代码后,发现每次刷新页面的时候,都会调用这个接口7次,这种调用太频繁了。同时代码中发现了大量JSON转换、序列化的情况,查了一些资料后发现这种行为确实会导致YGC频繁操作。


于是优化代码逻辑,刷新页面的时候调用一次接口就行,数据一次性传给前端,而不是多次调用。同时将没有必要的JSON转换代码优化掉。按理说现在的性能应该可以提升不少。打包、上传、重新观察。


(五)问题还是存在


平稳了4天,在周五早晨高峰的时候,运行缓慢、负载高的情况又发生了。这下傻眼了,难道是有其他地方没有检查到吗。


这时想到一个问题,明明一直没有动这些服务器,为什么平稳运行了半年后突然出现问题,于是往其他方面去想,怀疑是从公网IP进来到应用服务器中的某条链路存在问题。于是尝试着断掉公网链路,去压测放在内网的这些应用,竟然不会出现之前的问题。


于是检查公网到内网的专线网络请求情况,发现出口带宽最高就只能到200M,就是早高峰的时候,而当时买的专线带宽是可以到500M的。因此怀疑是带宽满了导致请求进不来堵塞在公网的Nginx服务器上,而用户发现运行缓慢后频繁去刷新,导致大量的Tcp连接time_wait。于是赶紧联系相关服务商对网络带宽情况进行检测,果然500M的带宽直接打了折扣,联系相关人员处理这方面的问题。


同时一些静态资源放在私有云的服务器上也会导致网络流量大,将这些静态资源分离到公有云的Nginx服务器上,来降低这条专线的网络压力。


(六)后续措施


后续观察来看,问题应该是解决了,当时发生宕机时,是用户反馈上来的,这一点很不合理,后续需要做好服务的监控等各项措施。同时在整体的排查问题时,也解决了一些虽然不是问题根源,但也需要优化的地方。


我是鱼仔,我们下期再见!



相关文章
顶丰某个客户死机的计算过程
顶丰某个客户死机的计算过程
|
SQL 监控 网络协议
线上故障如何快速排查?来看这套技巧大全
有哪些常见的线上故障?如何快速定位问题?本文详细总结工作中的经验,从服务器、Java应用、数据库、Redis、网络和业务六个层面分享线上故障排查的思路和技巧。较长,同学们可收藏后再看。
线上故障如何快速排查?来看这套技巧大全
|
3月前
|
消息中间件 Java 调度
一次线上服务CPU100%的排查过程
文章记录了一次线上服务CPU使用率达到100%的排查过程,通过使用top命令和jstack工具确定了导致高CPU使用的线程,并分析了Disruptor组件的不当配置是问题原因,通过修改组件的策略成功解决了问题。
77 0
|
4月前
|
缓存 Java Linux
开发与运维内存问题之线上遇到故障,使用jstat命令发现Old区持续增长如何解决
开发与运维内存问题之线上遇到故障,使用jstat命令发现Old区持续增长如何解决
46 2
|
4月前
|
Java BI 运维
开发与运维配置问题之升级机器配置后出现频繁的GC问题和超长的GC时间如何解决
开发与运维配置问题之升级机器配置后出现频繁的GC问题和超长的GC时间如何解决
35 1
|
6月前
|
监控 数据安全/隐私保护 iOS开发
服务器监控新利器:ServerBee带你看透服务器运行状态
服务器监控新利器:ServerBee带你看透服务器运行状态
153 0
|
运维 监控 前端开发
记一次线上 bug 的排查分析过程及总结
记一次线上 bug 的排查分析过程及总结
记一次线上 bug 的排查分析过程及总结
|
缓存 JSON 运维
如何避免大规模线上故障
如何避免大规模线上故障
174 0
|
SQL 固态存储 关系型数据库
经典案例:磁盘I/O巨高排查全过程(1)
经典案例:磁盘I/O巨高排查全过程
296 0
经典案例:磁盘I/O巨高排查全过程(1)
|
SQL Java 数据库连接
线上运行的项目突然变得很卡如何排查?
线上运行的项目突然变得很卡如何排查?