记一次zabbix server反复重启故障的排查

现象

最近遇到一个非常操蛋的故障,现象就是zabbix server在一次配置优化的过程中进行重启,

却在启动的过程反复重启,无法成功启动。

起因

最近告警量突增,从6W(每天)飙升至8W+,引发的后果就是邮件队列堆积,始终有大量的

邮件堆积着发送不出去。

于是我和主管开始一起进行配置的优化,改了SenderFrequency、StartPollers等参数,

然后进行重启,本来正常的一次重启,但观察重启的过程中却发现大概一个小时的时间

zabbix server进程就会进行一次重启。

观察zabbix server日志

检查server 日志,发现重启前后的报错:


8550:20140714:180316.484 One child process died (PID:9317,exitcode/signal:11). Exiting ...
8550:20140714:180316.600 syncing history data...
8550:20140714:180316.367 syncing history data... 63.451777%
8550:20140714:180316.234 syncing history data done
8550:20140714:180316.234 syncing trends data...


8550:20140714:180458.702 syncing trends data done
8550:20140714:180458.702 Zabbix Proxy stopped. Zabbix 1.8.15 (revision 29655). 
36451:20140122:152709.436 Zabbix Proxy stopped. Zabbix 2.2.1 (revision 40808). 

发现是由于某个子进程退出导致的zabbix server 主进程退出的。那重启就很合理了,我们

有计划任务会做定时检查存活状态,进程不在就会进行再次的启动。

但是为啥子进程会退出呢?

追溯变动

系统不好莫名其妙的故障,所谓no zuo no die,联想到今天下午的活,就是

进行了配置的优化,之后才导致这个反复重启的故障的,那么肯定是配置变化导致的。

当时做的优化主要是加大了StartPollers等几个配置项,而这几个配置项主要导致

启动的进程增大,随着带来的内存使用增大。

回滚配置

来不及想那么多,赶紧回滚吧。fuck,发现操作的时候直接修改了,没有进行备份,虽然

这个一般没啥事,手动凭记忆修改回原来的参数,重启,发现故障还在,跑半个小时左右

依旧会有One child dead 随后server退出的问题。。

swappiness

配置虽然回滚了,还是挂了。那说明还是环境变了,联想到整个优化过程,主管和我分别都

进行了配置的修改,我没备份,看了他的操作,同样没有备份。。而且由于是我们分别

进行的修改,所以我没有办法得知他修改了那些配置项,自然也没办法回滚。只好一行行的

过配置,尽量按照官方的建议、默认值去修改。

再次启动,依旧不行。等等,我忽然想到了,在整个调优的过程中,我看到当前物理内存

富余很多的情况占用了swap就随手该了swappiness参数,将默认的60改成为0。

OOM Killer

我忽然想起了神马,swappiness是控制swap使用的一个参数,那可能会导致神马后果呢?

当为0时,系统会尽量使用物理内存而不是swap分区,极端情况下可能导致OOM killer。

次奥,会不会是这货导致的zabbix server反复重启的呢? 忙晕了,居然忘记了去看messages。


Jul 14 18:03:16 zabbix-jxq-58 kernel: Out of memory: Kill process 9320 (zabbix_server) score 50 or sacrifice child
Jul 14 18:03:16 zabbix-jxq-58 kernel: Killed process 9320, UID 502, (zabbix_server) total-vm:1660632kB, anon-rss:1952kB, file-rss:608428kB
Jul 14 18:03:16 zabbix-jxq-58 kernel: zabbix_server invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Jul 14 18:03:16 zabbix-jxq-58 kernel: zabbix_server cpuset=/ mems_allowed=0
Jul 14 18:03:16 zabbix-jxq-58 kernel: Pid: 9306, comm: zabbix_server Not tainted 2.6.32-letv.2.220.4.1.el6.x86_64 #1
Jul 14 18:03:16 zabbix-jxq-58 kernel: Call Trace:

果然是这货把我干掉了。。

故障处理

如何控制oom-killer

知道了故障原因,修复起来就简单了,防止oom-killer 被我的zabbix server下手呗。

oom-killer 触发的原因都是内存不足导致的,而内存不足通常是由于内存超分配导致的。

关于linux内核的超分配是由overcommit_memory参数控制的(/proc/sys/vm/overcommit_memory),

关于参数的解释大神都有很详细的解释了,我就直接拿来用了:

  • 0:启发式策略,比较严重的Overcommit将不能得逞,比如你突然申请了128TB的内存。

    而轻微的Overcommit将被允许。另外,root能Overcommit的值比普通用户要稍微多些。

  • 1:永远允许Overcommit,这种策略适合那些不能承受内存分配失败的应用,比如某些科学计算应用。

  • 2:永远禁止Overcommit,在这个情况下,系统所能分配的内存不会超过swap+RAM*系数

    (/proc/sys/vm/overcmmit_ratio,默认50%,你可以调整), 如果这么多资源

    已经用光,那么后面任何尝试申请内存的行为都会返回错误,这通常意味着此时没法运行任何新程序。

由于默认设置是0,所以导致了我的zabbix server一开始是可以轻微的超额申请到所需的

内存的,但当运行到一段时间之后系统就会因为严重缺乏内存到触发oom-killer。

杜绝内存超分配

如果没有内存超分配的问题,那系统永远都只会分配可分配的内存,即系统永远不会严重缺乏内存,
自然也不会触发oom-killer。

<pre> echo "2" >/proc/sys/vm/overcommit_memory </pre>

恢复默认的swappiness

swappiness设置为0的情形一般为物理内存充足,例如大内存的情况下。我简单的根据

当时的情况就设置为0是欠考虑的,更稳妥的做法是应当参考历史数据。

而且设置为0确实在内存不足的时候更容易触发oom-killer,这里我们还是恢复默认值:

<pre>echo "60" >/proc/sys/vm/swappiness</pre>

经验教训

这次的优化过程犯了非常非常多的错误。大致总结下如下:

  • 不要一次优化多个配置,更不能多个人分别取优化配置!

  • 做修改哪怕只是一行的时候同样要记得备份

  • 不要想当然的去优化内核参数,例如swappiness等重要参数

  • 多看日志,勤看messages

其实大部分都是耳熟能详的东西,太阳底下无新事,但就是老生长谈的东西依旧要时刻

牢记在心,一句话对线上要有敬畏之心。

参考

3 Responses to “记一次zabbix server反复重启故障的排查”

  1. xdays says:

    这个评论支持markdown的呀,不错

  2. queque821 says:

    不错啊,经验值得学习。

Leave a Reply

Your email address will not be published. Required fields are marked *


To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax