服務掛了,怎么自動恢復?
大家或許都碰到過這樣的情況:
tomcat掛了,站點應用訪問不了
service出core了,服務掛了
架構設計上,避免單點,使用故障自動轉移固然能夠保證系統(tǒng)的高可用,是否還有其他的方案,讓掛掉的服務自動啟動呢,這里給大伙推薦一個常見的運維工具 supervisor。
畫外音:supervisor是很常見的運維工具,以下幾個小問題旨在讓不熟悉的同學簡單了解相關原理,獻丑了。
supervisor是什么?
答:用Python開發(fā)的通用的進程管理工具。
supervisor有什么用?
答:supervisor能把一個普通進程變?yōu)楹笈_daemon進程,并監(jiān)控進程狀態(tài),在進程異常退出時能夠自動重啟(或者告警),同時還提供一些相關的管理功能。
supervisor是怎么做到的?
答:supervisor通過fork/exec的方式,把被管理的進程當作其子進程來啟動,在被管理的子進程異常退出時(例如tomcat出異常掛掉,或者服務出core掛掉,或者收到異常信號掛掉),作為父進程可以獲取相關信息,以選擇后續(xù)如何處理。
之前沒用過supervisor,這玩意是否靠譜?
答:額,supervisor誕生10年以上了,絕對靠譜,絕大部分運維同學都熟知它。
作為程序員,了解一些運維的知識有用么?
答:額,知道“&”與“nohup”的區(qū)別,對寫程序可能沒幫助,但對理解整個技術體系及思路肯定是有好處的。
希望沒有浪費這一分鐘。
調研:“&”與“nohup”的區(qū)別是啥呀?
測試代碼如下:
是一個輸出hello與循環(huán)輪數(shù)的死循環(huán)程序,每輸出一行就休眠1秒。
使用 ./a.out 前臺運行程序,會是什么效果呢?
程序每隔一秒會在終端輸出一個字符串。
此時如果鍵入Ctrl+C?,程序會收到一個SIGINT信號,如果不做特殊處理,程序的默認行為是終止(如上圖)。
使用 ./a.out& 后臺運行程序,會是什么效果呢?
如上圖:
首先會在終端顯示進程號是32389
鍵入Ctrl + C,發(fā)出SIGINT信號,程序會繼續(xù)運行
need-to-insert-img
ps確認一下,確認進程依然在運行,進程號是32389。
此時如果關掉session,程序會收到一個SIGHUP信號,此時會怎么樣呢?
ps再次確認,可以看到關閉session之后,進程號是32389的a.out進程也關閉了。
使用nohup ./a.out 又會是什么效果呢?
使用nohup 運行程序a.out,會發(fā)現(xiàn):
前臺沒有出現(xiàn)進程號
有一個“忽略輸入,輸出至nohup.out”的提示
hello的輸出也沒有出現(xiàn)在前臺
手動ps看進程號,這次a.out的進程號是32437。
此時如果關掉session,程序會收到一個SIGHUP信號,程序會不會關閉呢?
關掉session后,再次ps看一下,ID為32437的a.out進程還在。
這些只能通過kill把程序干掉了,killall之后,ps查看進程已經關閉。
killall之后,查看發(fā)現(xiàn)多了一個nohup.out文件,不過這個文件的大小是0,有點奇怪,啟動程序的時候,明明提示了“appending output to nohup.out”呀,先把問題遺留在這,測試一下Ctrl +C。
仍如上圖,使用nohup啟動a.out,如果鍵入Ctrl+C?,程序收到SIGINT信號后,直接關閉了。
最后測試一下nohup和&同時使用,即用nohup./a.out &運行程序,又會是什么效果呢?
使用nohup ./a.out &運行程序后,可以看到:
會在終端顯示進程號是32524
也會有一個“忽略輸入,輸出至nohup.out”的提示
鍵入Ctrl + C,發(fā)送SIGINT信號,似乎沒反應。
關閉session,發(fā)送SIGHUP信號,再來看看。
ID為32524的進程依然存在,后續(xù)也只能用kill來關閉它。
結論
使用&后臺運行程序:
結果會輸出到終端
使用Ctrl + C發(fā)送SIGINT信號,程序免疫
關閉session發(fā)送SIGHUP信號,程序關閉
使用nohup運行程序:
結果默認會輸出到nohup.out
使用Ctrl + C發(fā)送SIGINT信號,程序關閉
關閉session發(fā)送SIGHUP信號,程序免疫
平日線上經常使用nohup和&配合來啟動程序:
同時免疫SIGINT和SIGHUP信號
同時,還有一個最佳實踐:
不要將信息輸出到終端標準輸出,標準錯誤輸出,而要用日志組件將信息記錄到日志里
尾巴
nohup啟動a.out,程序終止后,為啥nohup.out的大小是0?“hello”的字符串哪去了?