服务器崩溃原因分析

来源:捕风 发布时间:2018-12-08 14:56:57 阅读量:1044

分析这个问题的过程还是挺曲折,如果不想看繁琐的分析过程,请直接跳到结论

 

我们小组的成员请耐心看一下过程,积累一下经验,到用户现场是能学习很多东西的,以后你们要争取到用户现场,呵呵

 

---------------------------------------------------------------------------------------------------------------------------------------------------------

周一下午到移动时发现服务器的情况是这样的

1.ESServer内存达到差不多200M,且以缓慢的速度不断上升,ESServer进程一直占用CPU约6%-10%

2.服务器生成了一堆大小为0KB的DUMP

3.有大量因没有管理网段的客户端不断地每隔一分钟取策略

4.日志只有很少

---------------------------------------------------------------------------------------------------------------------------------------------------------

 

---------------------------------------------------------------------------------------------------------------------------------------------------------

在现场解决了两个问题

1.配置管理网段,让客户端不再取策略,并且重启ESServer,CPU占用率降了不少,平均1%-2%(且不是一直占用),内存没有发现上升(不排除是以更慢的速度上升,要等后面观察)

2.日志太少的原因是因为INI配置的日志文件只有10M,且只有一个备份,后将参数改为了1G(有一个奇怪的现象是,服务器的日志已经成功写入文件,但文件的修改时间一直不变)

---------------------------------------------------------------------------------------------------------------------------------------------------------

 

---------------------------------------------------------------------------------------------------------------------------------------------------------

在重启ESServer服务器时,很“有幸”地遇到一个崩毁,生成了55M的dump,赶紧拿回来分析

 

1.经过一番分析,发现崩毁是某个锁在已经被删除的情况下还继续使用导致

2.分析了代码,这个锁在服务器停止前都不会被删除的,而这次崩毁刚好又是在我停止服务器时发生的

3.写个模拟这种情况的测试程序,肯定也能这样崩毁,但毕竟这个程序不是服务器,只能作出推断,是多线程造成的问题,当停止服务器时,对象已经销毁,但还有线程刚好在用这个锁,这是一个很偶然的情况(T_T)

 

到这里,发现这个崩毁竟和之前的周期性崩毁没多大关系……(我崩毁了……),因为:

1.上面的崩毁是在一个很偶然的情况下发生的,很难周期性发生

2.上面的崩毁生成了55M的dump,周期性崩毁只生成了0KB的dump

---------------------------------------------------------------------------------------------------------------------------------------------------------

 

---------------------------------------------------------------------------------------------------------------------------------------------------------

问题还是没有找到,但既然怀疑这部分代码有多线程问题,就从这里出发查找:

1.发现代码里面这部分用得最多的就是日志模块,联系到那天国富跟我说他将日志参数从info改为debug时可能可以加快问题的发生,我就在服务器专门开两条线程不断地写日志,发现下面了问题

2.大量的日志写入,导致待写入日志的队列内存不断升高(因为写入文件的速度和写入内存的速度不是一个等级导致的),导致最后因空间不够,list在pushback的时候发生崩毁(为何stl会实现成这样还得深究)

3.以服务启动时,在崩毁的时候竟然生成了一个0KB的dump,“大喜”,因为这和移动的现象很类似(内存高,0KB的dump)

 

---------------------------------------------------------------------------------------------------------------------------------------------------------

其实以前天珣的代码编写者估计也想到这个问题,他限制了队列的最大长度是1024,但为什么还会出现这个问题呢,原来又是多线程和判断不严谨的问题,且看下面分析

1.在进入队列前,会先锁定然后判断队列是否已经满了,但这个锁在IsFull()后就解锁了,就存在如果同时有多线程PUT的时候,大家都做完IsFull()这个函数后再做doPut(),而判断队列是否满又竟然只用了“==”,就造成了队列大于1024,队列还会继续增加的情况。

2.最简单的修改方法就是将“==”改为“<=”,虽然没有改变多线程问题的本质,但足以很好地修复这问题

---------------------------------------------------------------------------------------------------------------------------------------------------------

 

结论:

1.这个问题估计是一直都存着的,只是需要条件触犯。在移动,大量客户端重复取策略,日志文件增长得很快(开了DEBUG更快),内存CPU很高,且和我这里重现的现象很类似,所以现阶段只能推断是这个原因造成的。但不明白的是,建行也出现过大量客户端重复取策略,却没有这种崩毁。

2.现在配了管理网段,客户端不再重复取策略,日志改为info,增加比较慢,问题应该会有所缓和,国富可先不跟移动说,再观察那边服务器情况一段时间。要修复的话只需按上面说的修复即可。

 

看来多线程的确是一个博大精深的问题,我由此担忧6694客户端这么多线程会不会埋着什么雷呢?

 

一切只是推断,需要时间验证,以上权当学习总结

--------------------- 



标签: 服务器搭建
分享:
评论:
你还没有登录,请先