互联网系统重启日

北京时间今天早上7:59:59,坚果云的所有Linux 操作系统 (CentOS 6.2)都出现CPU利用率暴涨的现象,主要影响的进程包括Java,MySQL等。直接重启Java和MySQL不能解决问题。后得知,该现象不仅发生在坚果云的服务器,很多互联网公司的服务器都在这一刻出现了不同程度的CPU利用率增长!

经过我们紧急的分析和调试,发现是因为操作系统内核在处理闰秒的时候,导致部分试图获取当前系统时间的进程出现Live Lock,也就是说,某个进程/线程在查询系统时间的时候,进入了一种类似死循环的状态,CPU利用率很高,同时不能完成时间查询。

我们猜测JVM和MySQL试图通过CPU硬件晶振的数据获得当前精确的时间,由于闰秒的关系,这个时间和操作系统维持的墙上时间(Wall Time,也就是显示给用户看的时间)不一致,导致了这个问题。

系统时间对于各种服务器程序尤为重要,例如在坚果云的系统中,很多节点都定期收集和报告系统状态,如果系统时间无法获取,可能导致部分节点被误判为故障,自动引起一系列不必要的故障恢复动作。

通过twitter, 邮件列表,论坛等其他媒体,我们发现很多互联网服务商都碰到类似问题,并且给出的方法多是重启服务器。坚果云团队戏称这是互联网全网统一重启服务器的日子。

与大家一样,我们首先选择的方式是按照顺序重启所有服务器,重新启动服务器确实能够解决这个问题。不过这个过程耗时长,而且容易出错。

幸运的是,谢谢Mozilla的一篇blog, 也谢谢Google快速灵活的实时索引,我们在重启服务器的过程中,发现了如下更简单的解决办法:

$ cat files/bin/leap-second.sh
# this is a quick-fix to the 6/30/12 leap second bug

if [ ! -f /tmp/leapsecond_2012_06_30 ]
then
/etc/init.d/ntpd stop; date `date +"%m%d%H%M%C%y.%S"` && /bin/touch /tmp/leapsecond_2012_06_30
fi

这个脚本只是简单的强制重置系统时间,从而让系统中所有时间回到同步的状态。完成后,你可以确认所有服务的状态回到正常,然后手动重启ntp服务。类似mozilla, 我们也使用puppet将该脚本在所有服务器上执行。

或许碰到问题的管理员都可以用这个办法解决。这是使用这个方法后的CPU利用率变化。

最后,希望航空航天,医疗等等重要系统不会受到这个问题的影响。在这些领域,重启系统很可能会造成巨大的伤害。