我們的項目需要一個啟動一個外部的Jetty server。發現每次kill了這個jetty的進程后,系統會自動啟動一個jetty。追查下去發現,原來是在/etc/init.d/jetty 腳本的start 函數里 使用了
initctl start jetty
而我們預想的start函數實現是這樣的:
java -jar start.jar
開來古怪就在initctl了。為了說清楚initctl,我們需要先回顧一下歷史。
在SystemV這個版本的unix中,系統啟動首先是啟動init進程。這個進程會按照runlevle啟動/etc/rc[0-6].d 目錄下的腳本。這里rc后面的數字就是runlevel。舉個例子,在圖形界面打開以前,runlevel=5;如果系統啟動了圖形界面,那么runlevel就進入到6.那么/etc/rc6.d里面的腳本就會被一個一個的執行。這些腳本其實都是到/etc/init.d/下的腳本的軟鏈接。
注意上面講到啟動順序是一個一個的執行,這不可避免的帶來串行的時間開銷。於是有了System V init 的改進版 “upstart”. initctl 就是upstart提供的一個命令。upstart 的一個優化就是使用的事件驅動,這樣啟動服務A的時候,不用等待A的結束就可以啟動服務B了。在upstart的概念里,我們把服務稱作JOB。使用命令
initctl start JOB
啟動的JOB以init進程為父進程。當JOB的進程被殺死后,init進程會自動重新啟動JOB。這就是 initctl start JOB 和 service JOB start 的主要區別吧。
那么如何創建一個自己的JOB呢?
需要在/etc/init/目錄下創建一個.conf 文件。比如說我們的JOB叫 mywork。那么需要創建文件/etc/init/mywork.conf
下面給一個mywork.conf的例子:
exec python -m SimpleHTTPServer 8111
這端代碼會啟動一個http server監聽 8111 端口。
建立了文件后,可以運行命令 initctl start mywork, 這樣8111端口就被監聽了。可以試試 curl localhost:8111,你會收到一段SimpleHTTPServer提供的默認HTML。你也可以嘗試這殺掉監聽8111端口的進程,不過很快腳本mywork.conf就會重新啟動監聽8111端口。
怎么寫mywork.conf 呢? 可以參考一下:http://www.mike.org.cn/articles/understand-upstart/