阿裡雲售後工程師快速排查發現 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**** ~]# chkconfig --list|grep redis-server redis-server 0:off 1:off 2:on 3:on 4:on 5:on 6:off [root@iZ** ~]# chkconfig redis-server --level 2345 off [root@iZ** ~]# chkconfig --list|grep redis-server redis-server 0:off 1:off 2:off 3:off 4:off 5:off 6:off [root@iZ**** ~]# reboot
重啓服務器後,神奇的一幕出現了,服務器再次停留在redis 啓動界面。
2、此刻我是懷疑人生的,難道redis服務沒有禁用成功。
爲排除原系統干擾,選擇通過LiveCD方式切換chroot檢查原系統配置。發現redis服務確實已關閉。
[@bash]$ sudo su [root@bash]# mount /dev/xvda1 /mnt[root@bash]# chroot /mnt [root@bash]# chkconfig --list|grep redis-server redis-server 0:off 1:off 2:off 3:off 4:off 5:off 6:off [root@bash]# cat /etc/rc.local #!/bin/sh # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't touch /var/lock/subsys/local
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.locall rwxrwxrwx. 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 [root@bash]# mount /dev/xvda1 /mnt [root@bash]# cd /mnt/root [root@bash]# ls -al |grep log|wc -l0
但是,這個服務到底是怎麽起來的呢?
破雲見日
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、經驗能提高我們快速排障的效率,但有時候也是這些經驗,會形成排查時的慣性思維,導致對細節的忽略。
不足之處,請大家隨時拍甎。感謝。