管理與啟動你的程式: Supervisor

Supervisor: A Process Control System
最近的日子都在與 Python 奮戰相處, 因為平常在寫的時候都有習慣將一些小小心得記下來, 但是整理這件事打從心底就懶得動手 。趁著今天感覺比較悠哉的時刻 , 分享一下日前一邊玩、一邊研究的一個厲害開源程式。

由於架構實作在一番功夫之後選定用 Python 2.7.3 + Tornado + Nginx, 在撰寫程式碼的過程中由於我覺得同時啟動多個 process 似乎是件挺麻煩的事情, 基於懶人懶到底、大家一起懶工程師喜歡標準化的心理 , 在拜求谷歌大神後, 我就開始玩起 Supervisor 這套在軟體副標題中直接清楚寫明: A Process Control System 的程式管控系統。

註: 這篇部落格的安裝及說明都是在 CentOS 6


安裝


在Python的世界中 , 因為有了 easy_install 和 setuptools 讓安裝都很簡單, 直接下一個指令就安裝完了:
easy_install supervisor
如果沒有網路安裝 , 下載原始碼解壓縮後執行:
python setup.py install
其實也是挺輕鬆的。

複製範例設定檔


執行以下指令可以複製一個範例的設定至 /etc/supervisord.conf (預設位置)
echo_supervisord_conf > /etc/supervisord.conf

加入一個新程式


我喜歡採取個別程式有個別設定檔的方式來管理程式, 所以請至 /etc/supervisord.conf 中將欲匯入的資料夾路徑給設定好。(把前面的 ; 拿掉, 並改為自己要放設定檔的位置。)
;[include]
;files = relative/directory/*.ini
然後加入開一個新檔 myapp.ini 放進去就完成一半了。
[program:myapp]
user=andre
numprocs=4
command=python /var/myapp/src/web.py
process_name=%(program_name)s-%(process_num)s
autostart=true
stdout_logfile=/tmp/myapp.log

開始使用 Supervisor


Supervisor 有個 daemon 程式及一個方便操作使用的文字介面管理工具, 分別可以用下面兩個指令來啓動:

Daemon:
/usr/bin/supervisord
Management Tool:
/usr/bin/supervisorctl
Daemon 的指令就是將 Supervisord 喚醒開始工作, 如果設定檔內的 autostart 為 true, 那同時也會啟動你先前設定好的程式。

Management Tool 在輸入上面指令後會進入控制台, 可以看到目前各個執行程式的健康狀況, 輸入 help 可以查看可執行的指令, 接著就可以依照所需要的目的進行動作。
supervisorctl screenshot - help

管理遠端 Supervisor 


Supervisor 提供 XML-RPC 來操作遠端的 Supervisord, 可以取得資訊而且也可以進行一些操作, 利用下面一個小範例可以知道有哪些 API 可以用:
import xmlrpclib
server = xmlrpclib.Server('http://localhost:9001/RPC2')

print server.supervisor.getState()
print server.system.listMethods()
print server.system.methodHelp('supervisor.getProcessInfo')
print server.supervisor.getAllProcessInfo()
上面四行 print 分別執行結果:
{'statename': 'RUNNING', 'statecode': 1}

['supervisor.addProcessGroup', 'supervisor.clearAllProcessLogs', 'supervisor.clearLog', 'supervisor.clearProcessLog', 'supervisor.clearProcessLogs', 'supervisor.getAPIVersion', 'supervisor.getAllConfigInfo', 'supervisor.getAllProcessInfo', 'supervisor.getIdentification',
... 
'supervisor.tailProcessStderrLog', 'supervisor.tailProcessStdoutLog', 'system.listMethods', 'system.methodHelp', 'system.methodSignature', 'system.multicall']

Get info about a process named name

@param string name The name of the process (or 'group:name')
@return struct result A structure containing data about the process

[{'now': 1361332825, 'group': 'myapp', 'description': 'Exited too quickly (process log may have details)', 'pid': 0, 'stderr_logfile': '/tmp/myapp-0-stderr---supervisor-eGXJPm.log', 'stop': 1361327559, 'statename': 'FATAL', 'start': 1361327559, 'state': 200, 'stdout_logfile': '/tmp/usher.log', 'logfile': '/tmp/usher.log', 'exitstatus': 0, 'spawnerr': 'Exited too quickly (process log may have details)', 'name': 'myapp-0'},
...
, {'now': 1361332825, 'group': 'myapp', 'description': 'Exited too quickly (process log may have details)', 'pid': 0, 'stderr_logfile': '/tmp/myapp-3-stderr---supervisor-2Ar_Q8.log', 'stop': 1361327559, 'statename': 'FATAL', 'start': 1361327559, 'state': 200, 'stdout_logfile': '/tmp/usher.log', 'logfile': '/tmp/usher.log', 'exitstatus': 0, 'spawnerr': 'Exited too quickly (process log may have details)', 'name': 'myapp-3'}]

常見問題

  1. Stucked in Nginx with Supervisor?
    A: Nginx is on daemon by default. Set 
    daemon off;
    in your nginx.conf. (More: http://wiki.nginx.org/CoreModule)
  2. Why does Nginx always show "502 Bad Gateway" when I use Tornado and unix socket?
    A: That may be caused by permission issues. Start Supervisor by "root" and make sure both Nginx and Tornado app can access the unix socket files at the time. (See parameter: 'user')

留言