一个定时任务导致的业务频繁宕机事故

现象和背景:

最近,一个客户的mongodb经常发生内存不足的情况,由于对业务也未产生太大影响,也没有太多关注。然而近期业务发生频繁宕机,尤其近日,发生宕机的概率越来越大,一天宕机次数达7、8次之多,虽然每次仅有一分钟故障时间,但整体影响还是不小。

历史处理方式:

通过对java内存的监控,调整gc策略稍有所缓解,又对JVM整体内存进行调整,从原先的3G调整为7G,仍无法解决问题。后同事对该业务增加了定时监测应用接口的功能,如发现业务接口宕机,就自动重启Java应用。常说“重启是万能的”,却发现在这个业务场景下,重启就显得无能为力。

分析:

1、首先查看主机监控(从内存、CPU、流量、IO、TCP等角度综合分析),通过监控图的查看,我们发现异常时间时,Java应用主机的流量比较高。

2、流量高的几个原因,一个是外部用户访问量(或攻击类)的增加,从而导致应用主机流量增加,另一个是内部功能调用,应用主机与其他某些业务之间有关联,从而导致流量增加。经过仔细分析后,我们排除了外部用户量增加或者被攻击的情况。然后我们筛选了所有服务器的近3个小时的网络流量,发现mongodb和另一个业务的流量很高。一个定时任务导致的业务频繁宕机事故_第1张图片
3、跟客户沟通后,排出了另一个业务流量高导致当前应用主机异常的可能。然后着重JAVA应用主机和Mongodb服务器的交互的排查。

4、既然是网络流量分析,就少不了ss工具,但通过ss的定时监控发现,应用主机和Mongodb数据库的之间的连接数比较稳定,哪怕是在业务异常情况下,连接数也未有明显变化。

5、开启mongodb日志,常规情况下我们开始了1s以上的慢查询日志,常规执行语句没有开启。

开启命令:db.setProfilingLevel(2,0);具体见参考内容

6、开启后,mongodb的日志以每分钟大概70M左右的速度在增长。10分钟的日志量差不多600M,语句执行量还是有点可观的。

7、既然日志出来,我们对日志进行分析,mongodb比较好的日志分析工具是mtools。安装文档和使用说明见参考。然后是一堆的执行语句分析,从整理结果看,26-31分,这6分钟的执行量都远远超出了正常值。mongodb执行语句统计
同样也可以利用mtool工具去分析,命令:mloginfo mongod.log --queries

10分钟的数据统计情况如下然后一个定时任务导致的业务频繁宕机事故_第2张图片
再根据的情况,将对应SQL语句发给客户。

8、到这里差不多可以了,研发童鞋可以通过大量的执行的SQL去找到大概是什么业务在跑了。但在观察业务流量监控图形的时候,突然发现一个很规律的显现,大概每30分钟就有一次流量高峰,而每次流量高峰都将导致一次业务宕机。![规律性流量波动优化确认

于是将上述问题反馈给研发,经确认代码中的确存在这样的定时任务,每次定时任务执行时间大概要10分钟,而且是几台应用服务器同事执行。建议研发童鞋将定时任务独立出来用其中一台服务器单独运行,但研发确认后,该定时任务是直接写入各应用服务器的内存的,没有共享,快速恢复比较困难。且定时时间与应用启动时间相关。

临时解决方案:

与研发童鞋商议后将定时任务更改为24小时一执行,几台服务器的启动间隔分别延迟30分钟后启动,比如A服务器启动后,B服务器上应用30分钟后再重启,避免定时任务同时执行时几个应用都无响应,导致业务异常。

建议:

定时任务实现可配置化,任务独立,不要与对外应用服务器混在一起同时运行,在版本发布时,指定其中一台应用主机执行定时任务,同时关于定时结果的共享,可采用redis,mongodb进行处理。避免多个应用同时处理或者定时处理实效的情况。

参考:

Mtools命令使用:http://blog.csdn.net/xiewen99/article/details/52452328

设置mongodb日志级别:http://blog.163.com/ji_1006/blog/static/1061234120134633710740/](https://img-blog.csdn.net/20181022145701330?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpcWl1bWFuMTgwNjg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

你可能感兴趣的:(一个定时任务导致的业务频繁宕机事故)