監控重啟進程的方案有很多種:
- 最簡單的方法,寫個腳本fork進程運行,然后waitpid,如果獲pid后就再次啟動
- 最土的方法,配置cron任務,固定時間運行腳本檢查進程是否存在,不存在則啟動
-
百度使用qmail里的supervised程序,通過supervised監管進程。
- 優點:supervised可以啟動daemon程序,對于非daemon需要采用nohup的方式啟動。
- 缺點:每個進程都要配置自己的supervised,無法做到統一管理。
- 百度對supervised進行過改造,線上有2個分支,基本功能類似,如:進程掛掉后的重啟次數、重啟前調用腳本處理、重啟時報警功能。
-
使用supervisord
supervisord是python寫的進程監控工具(http://supervisord.org/),網上也有很詳細的中文教程,提供2個工具supervisord和supervisorctl- supervisord 用來啟動supervisord
- supervisorctl start/stop/restart/status [process_name] 對進程進行控制和狀態查看
- 提供一個http server,能夠在瀏覽器查看和操作進程啟停。同時提供xmlrpc功能,可以自己編寫CLI程序遠程call supervisord的接口
- 缺點:不能對daemon程序監控,supervisord退出后會使被監管的進程也退出
-
使用monit
monit的功能基本上和supervisord類似,占用內存也非常少,大概在2M左右,不過實在不喜歡它的進程配置語法。- 優點:支持進程資源只用判斷,當進程使用cpu/mem超過多少進行重啟。當進程異常不斷重啟時,也支持各種條件。
-
使用god
god的功能和supervisord、monit比較類似,接下來會重點介紹God的相關功能
God 進程監控
God是由ruby編寫的進程監控框架(http://godrb.com),安裝、配置都很簡單,大概的功能如下:
優點:
- 啟動和控制都使用一個命令: god
- 可以管理daemon和非daemon進程
- 可以設置進程的uid、env、dir、log等參數
- 進程配置文件和supervisord類似,但使用ruby的語法。支持類似monit的,對進程使用資源和各種條件的控制
- 支持進程配置動態加載功能
- 支持把多個進程配置拆分成單獨的配置文件,類似include功能
- 支持通知功能,包括:Webhook、Email、Twitter、Jabber、Campfire等多個接口
- 根據PID的方式進行監控,GOD可以隨便升級和重啟
缺點:
- 不提供web端和rpc接口
- log查看stdrr/stdout 功能似乎不能正常work,不過我基本上用不到這個功能
- linux下采用2種方式檢測進程poll和event。root默認啟用event模式,如果啟動的進程錯誤,它會注冊一個proc_exit事件,但無法響應。
一、 安裝
需要有ruby環境,>= ruby 1.8.7,支持redhat、ubuntu、centos
1
|
[sudo] gem install god
|
二、 一個簡單的實例
-
編寫一個簡單的ruby程序,hello.rb:
1234loop doputs “hello God!”sleep 5end
-
編寫進程配置文件,hello.god:
123456God.watch do |w|w.name = “hello”w.start = “ruby /home/work/ruby/hello.rb”w.keepalive(:memory_max => 150.megabytes,:cpu_max => 50.percent)end
-
啟動god,加載配置,有2種方式:
- 啟動god同時加載配置: god -c hello.god
- 先啟動god,再加載配置: god && god load hello.god
這個時候可以用ps查看,hello.rb已經啟動起來。使用god status 可以查看到狀態如下:
1
|
hello: up
|
在hello.god配置中,我們配置了:memory_max和:cpu_max,當hello.rb使用cpu或mem超過我們配置的內容時,god就會重啟該進程。
使用如下命令,對進程進行各種控制,具體見god –help:
1
|
god start/stop/restart/status/monitor/unmonitor/remove/log [process_name]
|
三、 進一步使用
-
配置文件中加載其他god文件
1God.load “/home/god/conf/*.god”
- 已經啟動god后,使用god load 動態加載配置
- god pid文件,root啟動時在/var/run/god, 普通賬號在~/.god/
- god -D 非daemon方式運行God
- god status 看到的狀態有3種:up、unmonitored、error(一般不會出現)
- god支持設置uid,pid,dir,chroot,env等各種參數,詳細見godrb.com
-
進程啟動觸發郵件發送,配置如下:
1234567891011121314151617God::Contacts::Email.defaults do |d|d.from_email = ‘god@xxx.com’d.from_name = ‘God’d.delivery_method = :sendmailendGod.contact(:email) do |c|c.name = ‘wilbur’c.group = ‘developers’c.to_email = ‘wilbur@xxx.com’endw.transition(:up, :start) do |on|on.condition(:process_exits) do |c|c.notify = ‘wilbur’endend
四、 經驗分享
- 實際測試時,只有log功能不能正常工作
-
測試配置一個錯誤的w.start = “ruby ddd.rb”, ddd.rb不存在
-
在root環境下god默認使用event模式,由于該進程啟動命令錯誤,注冊一個proc_exit(pid_num)后,沒有再次啟動.
使用god status 查看,進程一直是up狀態,但查看進程pid不存在 -
使用poll模式進行進程監控,查看god日志。god不斷重啟該進程
使用god status查看,進程也是up狀態。查看代碼,因為god在啟動進程的時候會將它狀態變成up狀態,下次周期檢查時,發現進程掛了,又重啟,又將狀態修改為up狀態。
所以在任何時刻下查看進程都是up狀態,可以使用如下配置方式進行解決:123456789101112131415161718192021God.watch do |w|w.name = “hello”w.start = “ruby /home/work/ruby/hello.rb”w.keepalive(:memory_max => 150.megabytes,:cpu_max => 50.percent)w.lifecycle do |on|on.condition(:flapping) do |c|c.to_state = [:start, :restart]c.times = 5c.within = 5.minutec.transition = :unmonitoredc.retry_in = 10.minutesc.retry_times = 5c.retry_within = 2.hoursendendend#當進程異常,會導致god不斷重啟#使用:flapping條件#5分鐘內start或者restart進程 5次,如果啟動失敗,修改狀態為unmonitored#10分鐘后再次嘗試啟動,如果2個小時內,嘗試5次都失敗,徹底放棄
-
在root環境下god默認使用event模式,由于該進程啟動命令錯誤,注冊一個proc_exit(pid_num)后,沒有再次啟動.
- god使用ruby的drb進行通信,所以很容易寫一個web server+xmlrpc功能,通過drb控制god.
- god load對.god內容正確性沒有檢查,可以使用god load 加載一個ruby程序。
原文鏈接:http://zoomq.qiniudn.com/ZQScrapBook/ZqFLOSS/tree/item20081015105037-frameset.html
原創文章,作者:追馬,如若轉載,請注明出處:http://www.www58058.com/468