最佳实践:全省职业考试时服务器突然瘫痪,如何搞定?
更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud
本期云享团的分享嘉宾是闻战,擅长系统故障分析排查,热爱技术挑战。聚焦弹性计算方案应用。
对于云计算服务,闻战是这样理解的:“每一次托付,都是使命与责任并行!”
事件概述:
前几天,阿里云突然接到某省政务云反馈:即将进行的全省职业考试的服务器重启后无法访问,导致全省在线考试系统瘫痪,如果不尽快解决,将影响上万个准备了数月的考生,时间紧迫,要求紧急处理。阿里云售后工程师快速排查发现 Redis服务启动异常,导致后续启动条目卡住,随后尝试单用户chkconfig禁用该服务,优先保证启动系统。但是,重启后发现该组件再次启动,chkconfig多次强关无效。检查rc3.d、rc.local、profile、crontab等脚本并未发现针对redis服务的相关调用。
Hot点:
1、Linux启动流程。
2、服务启动顺序分析。
3、问题分析的方法思路。
影响程度:【紧急】
架构梳理:
情景复现:
1、主机启动后,ping测试,EIP无法ping通。
2、VNC检查ECS服务器状态,停在启动进度条,按ECS键查看启动过程,发现redis服务启动异常。
至此,小伙伴大多会初步判定redis服务启动异常,可以尝试禁用Redis服务后,优先保障系统正常启动,按提示写入相关语句到rc.local,进行后续排查,一个并不算太复杂的故障。
But,处理过程没有想象的这么顺利……
无法禁用的小强
1、重启服务器可以正常进入单用户模式,执行chkconfig命令禁用redis服务。
[root@iZ****<strong> ~]# chkconfig --list|grep redis-serverredis-server 0:off 1:off 2:on 3:on 4:on 5:on 6:off[root@iZ</strong>**<strong> ~]# chkconfig redis-server --level 2345 off[root@iZ</strong>**<strong> ~]# chkconfig --list|grep redis-serverredis-server 0:off 1:off 2:off 3:off 4:off 5:off 6:off[root@iZ</strong>**** ~]# reboot
重启服务器后,神奇的一幕出现了,服务器再次停留在redis 启动界面。
2、此刻我是怀疑人生的,难道redis服务没有禁用成功。
为排除原系统干扰,选择通过LiveCD方式切换chroot检查原系统配置。发现redis服务确实已关闭。
[@bash]$ sudo su
3、按照redis启动时的报错,在rc.local添加对应语句,检查rc.local 已经777有执行权限。保存重启后,还是卡在redis启动界面。
[root@bash]# echo “echo never > /sys/kernel/mm/transparent_hugepage/enabled”>>/etc/rc.local[root@bash]# ls -al /etc/rc.locallrwxrwxrwx. 1 root root 13 Aug 14 2014 /etc/rc.local -> rc.d/rc.local[root@bash]# reboot
曲线救国
由于时间比较紧迫,为保障优先恢复用户业务(全省职业考试),想了一个不是办法的办法:
在单用户下:先mv /usr/local/redis/bin/redis-server 进行重命名,由于开机找不到这个文件,系统会跳过加载。然后系统正常启动后,再mv把名称改回恢复业务。
但这始终不是一个长久的解决办法,问题的根源还是没有找到。
重整思路
哪里有些不对,忽略了什么细节呢?排查至此,有必要对之前的思路进行一次梳理重整。
1、单用户下能正常启动,把redis-server重命名也能正常启动,证明系统底层和内核是好的。
2、单用户和liveCD chkconfig验证,redis服务自启动是已经关闭的。
3、打点测试 rc.local和profile没有输出对应的log文件,说明系统还没有走到这一步就卡住了。也就是出现问题的环节,在加载rc.local之前。
[root@bash]# echo touch /root/rc_test.log >>/etc/rc.local[root@bash]# echo touch /root/pro_test.log >>/etc/profile[root@bash]# reboot //重启服务器进入liveCD模式[@bash]$ sudo su
但是,这个服务到底是怎么起来的呢?
破云见日
1、Linux启动流程
在【加电】→【启动内核】后,Linux进入【init】阶段,示意图如下。
2、分析推论
对比启动流程逐步检查,分析/etc/inittab文件,发现启动级别为5。默认该启动级别应该为3(这也是刚开始检查rc3.d目录没发现异常的原因之一)。
3、初见端倪
那么Linux启动时,会去加载/etc/rc5.d/目录中的服务配置,逐个检查该目录下的配置文件终于发现了端倪: S-1redis-server 这个文件,而我们明明在单用户和LiveCD中已经关闭redis服务,怎么还会出现这个服务的启动脚本呢。
随后通过chkconfig启用redis-server服务,对比rc3.d目录,确定了问题所在。
4、原来如此
正常情况下,我们启用一个服务后,会在对应的rc*.d启动目录下,生成一个该服务的启动配置文件。而rc5.d启动级别,redis-server却有两个启动脚本,其中一个还是负数?!
测试通过chkconfig 关闭redis-server服务时,S-1redis-server不受管控。也就是系统t启动的时候,还是会加载这个服务,而且是插队加载。
Linux读取rc*.d目录加载启动服务时,会顺序读取S开头的配置脚本,辣么……编号为负数的启动条目会跑在所有启动项之前,导致系统卡住,并且不受 chkconfig 管束!!!
各位官人、剩下您知道怎么解了吧?
经验和总结
1、用户现场业务受影响时,应本着业务保障的第一原则,如果快速排查不能定位问题,要考虑是否有途径先恢复业务。可以让用户创建一个镜像进行排查。
2、经验能提高我们快速排障的效率,但有时候也是这些经验,会形成排查时的惯性思维,导致对细节的忽略。
不足之处,请大家随时拍砖。感谢。