现象和背景:
最近,一个客户的mongodb经常发生内存不足的情况,由于对业务也未产生太大影响,也没有太多关注。然而近期业务发生频繁宕机,尤其近日,发生宕机的概率越来越大,一天宕机次数达7、8次之多,虽然每次仅有一分钟故障时间,但整体影响还是不小。
历史处理方式:
通过对java内存的监控,调整gc策略稍有所缓解,又对JVM整体内存进行调整,从原先的3G调整为7G,仍无法解决问题。后同事对该业务增加了定时监测应用接口的功能,如发现业务接口宕机,就自动重启Java应用。常说“重启是万能的”,却发现在这个业务场景下,重启就显得无能为力。
分析:
1、首先查看主机监控(从内存、CPU、流量、IO、TCP等角度综合分析),通过监控图的查看,我们发现异常时间时,Java应用主机的流量比较高。
2、流量高的几个原因,一个是外部用户访问量(或攻击类)的增加,从而导致应用主机流量增加,另一个是内部功能调用,应用主机与其他某些业务之间有关联,从而导致流量增加。经过仔细分析后,我们排除了外部用户量增加或者被攻击的情况。然后我们筛选了所有服务器的近3个小时的网络流量,发现mongodb和另一个业务的流量很高。
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分钟的执行量都远远超出了正常值。
同样也可以利用mtool工具去分析,命令:mloginfo mongod.log --queries
10分钟的数据统计情况如下然后
再根据的情况,将对应SQL语句发给客户。
8、到这里差不多可以了,研发童鞋可以通过大量的执行的SQL去找到大概是什么业务在跑了。但在观察业务流量监控图形的时候,突然发现一个很规律的显现,大概每30分钟就有一次流量高峰,而每次流量高峰都将导致一次业务宕机。