daemontools檢測進程,退出拉起
一、學習的原因:
為了實現在服務異常停止運行後,有一個監控程序能監控到它,並自動重新啟動這個服務。以下以tomcat為例子
二、工具supervise
Daemontools是一個包含了很多管理Unix服務的工具的軟件包。其中最核心的工具是supervise,它的功能是監控一個指定的服務,當該服務進程消亡,則重新啟動該進程。而要添加讓supervise監控的服務非常容易,只需要添加一個被監控的服務的目錄,在該目錄中添加啟動服務器的名字為run的腳本文件即可。
其中svscan工具是為指定的工作目錄(缺省是/service/目錄)下的所有子目錄中的每一個子目錄都啟動一個supervise進程,最多可以啟動多達1000個supervise進程(也就是工作目錄下可以有多達1000個子目錄)。其中每個子目錄下都會有一個名為run的用來啟動對應服務的腳本程序。Supervise會監控該服務,在服務消亡時使用run腳本來自動啟動該服務。若svscan的工作目錄下的子目錄的sticky位被置位,則svscan將為該子目錄啟動兩個supervise進程,一個監控子目錄中的run對應的服務,另外一個監控子目錄下的log子目錄的記錄服務,兩者之間通過管道來相互聯系。
Svscan每5秒鐘檢測一次子目錄,若出現新的目錄則為該目錄啟動supervise,若某個老的子目錄對應的supervise退出,則重新啟動它。
該軟件包的所有工具的詳細信息請參考在線文檔。daemontools最經典的搭配是和lighttpd一起使用
三、安裝
/pacakage目錄(你可以創建任意目錄,這裏使用package只是為了保持與英文作者的一致):
mkdir -p /package
chmod 1755 /package
cd /package
下載daemontools-0.76.tar.gz到/package目錄,解壓該包。
http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
tar xvzf daemontools-0.76.tar.gz
cd admin/daemontools-0.76
編譯並安裝daemontools程序
package/install
【註意】:如果在安裝過程中出現安裝失敗的提示,是因為daemontools 需要一個補丁daemontools-0.76.errno.patch,這個補丁在qmail包中有。或者修改daemontools 源代碼來修補這個bug
(修改方法:在src下的conf-cc文件的第一行最後添加如下代碼即可 -include /usr/include/errno.h
# vi src/conf-cc
在最後加上 -include /usr/include/errno.h
)
如果安裝成功,你可以用下面命令確認:
# ps -ef | grep svscan
# man svscan
此時你查看一下inittab文件:
# cat /etc/inittab
會發現原來daemontools是使用init的方式來保護自己的:
SV:123456:respawn:/command/svscanboot
通過strace命令你能看到系統每隔五秒會核對一下服務:
# strace -p `pidof svscan`
四、使用supervise程序進行程序管理監控
supervise的執行命令是supervise Path ,其中Path 是指定路徑,可以是相對路徑,也可以是絕對路徑。在Path路徑下,必須有一個run的腳本,supervise調用的就是這個腳本,並監控管理該腳本中運行的程序。
supervise的一個重要的功能就是可以檢測出run腳本中執行的程序是否正常工作,若發現其已經死掉,supervise將會重新執行run腳本,重新啟動指定程序。這對於很多服務端程序來說是十分必要的,沒有人願意在深夜2點的時候從被窩裏爬出來重新啟動服務器。
下面是一個簡單使用supervise的例子。
五、1)例子1
假定已經安裝好daemontools,建立一個test目錄,進入該目錄
mkdir /temp1
cd /temp1
在該目錄下寫一個簡單測試程序test.c:
編譯test.c輸出為test。
gcc -o test test1.c
編寫一個腳本run,來執行test程序,以便supervise進行調用。
#!/bin/sh
echo "start test!"
./test
退到上級目錄,執行 supervise temp1看看效果:
cd ..
supervise temp1
執行killall -9 test,殺死test進程,你會發現supervise會重新啟動test進程。當然如果程序core dump,supervise同樣會重新啟動程序。
C代碼
- #include
- #include
- int main(){
- int ix = 0;
- for(;; ix++){
- printf("%d\n", ix);
- sleep(1);
- }
- return 0;
- }
註意:當停止再次啟動supervise監控某目錄時,會提示:
supervise: fatal: unable to acquire /service/test/supervise/lock: temporary failure
這時刪除目錄下的supervise重新監控即可。
2)例子2 (java)
命令: mkdir /service/test
cd /service/test
ll
vi demo.java
Java代碼
- class demo{
- public static void main(String[] args) throws Exception{
- for(int i=0;;i++){
- System.out.println("i="+i);
- Thread.sleep(1000);
- }
- }
- }
javac -d . demo.java
vi run
Xml代碼
- #!/bin/sh
- echo -e "start test";
- exec java demo
chmod +x run
執行監控目錄 :supervise /service/test
[終端打印出來標號]
再開啟一個終端,查看正在執行這個命令的進程id,執行 ps -A
找到 java這個進程的id號,
執行 killall -9 java
看前一個終端,是不是打印又從新開始了,呵呵。這說明中斷之後supervise又啟動這個進程了
3)例子3
mkdir /tmp/test
cd /tmp/test
vi demo.java
[代碼同例子2]
javac -d . demo.java
vi run
Java代碼
- #!/bin/sh
- echo -e "start test2";
- exec java -classpath /tmp/test demo
chmod +x run
ln -s /tmp/test /service/test
ll /service
supervise /service/test
發現開始打印了,這時在另一個終端執行 killall -9 java ,則發現這個終端的打印又從新開始了,也就是殺掉進程之後立即又從新執行run了
4)實例4 監控tomcat啟動
假如tomcat 在redhat的 /var/tomcat6
在/service目錄下新建一個run文件,內容如下:
Java代碼- #!/bin/sh
- TOMCAT_HOME=/var/tomcat6
- exec ${TOMCAT_HOME}/bin/catalina.sh run
執行supervise /service
則發現tomcat啟動了。
測試: 新打開一個終端,ps -ef |grep tomcat
找到tomcat的id,執行 kill -9 [tid]
殺掉了tomcat但在之前的終端窗口上卻顯示重新啟動了tomcat。
daemontools檢測進程,退出拉起