一、學習的原因:
為了實作在tomcat服務異常停止運作後,有一個監控程式能監控到它,并自動重新啟動這個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。
【注】:好像用tomcat的./shutdown.sh指令不能使監控重新開機,出現異常,端口占用,可能是還沒等tomcat關閉監控就執行了啟動指令。
參考資料:1)官網:http://cr.yp.to/daemontools.html