今天湊空研究了下Supervisord,這是一款linux進程管理工具,使用python開發,主要用於在后台維護進程(類似master守護進程),可以實現監控進程的狀態、自動重啟進程等操作,便於一些服務的維護與監控。
安裝Supervisord
由於是用python開發的,因此使用pip安裝最為方便。
1
|
$ pip install supervisor
|
說明:安裝完成之后多了3個工具:echo_supervisord_conf、supervisorctl和supervisord。
Supervisord配置文件
首先可以使用echo_supervisord_conf命令獲取supervisor配置模板:
1
|
echo_supervisord_conf > supervisord.conf
|
說明:該命令在當前目錄下創建了一個文件名為supervisord.conf的配置文件,編輯配置文件:
1
|
vim supervisord.conf
|
來看看默認配置文件中的主要配置項:(還有一些配置不常用,可以忽略)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
[unix_http_server]
file=/tmp/supervisor.sock ; UNIX socket 文件,supervisorctl 會使用
;chmod=0700 ; socket 文件的 mode,默認是 0700
;chown=nobody:nogroup ; socket 文件的 owner,格式: uid:gid
;[inet_http_server] ; HTTP 服務器,提供 web 管理界面
;port=127.0.0.1:9001 ; Web 管理后台運行的 IP 和端口,如果開放到公網,需要注意安全性
;username=user ; 登錄管理后台的用戶名
;password=123 ; 登錄管理后台的密碼
[supervisord]
logfile=/tmp/supervisord.log ; 日志文件,默認是
$CWD/supervisord.log
logfile_maxbytes=50MB ; 日志文件大小,超出會 rotate,默認 50MB
logfile_backups=10 ; 日志文件保留備份數量默認 10
loglevel=info ; 日志級別,默認 info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ; pid 文件
nodaemon=
false ; 是否在前台啟動,默認是 false,即以 daemon 的方式啟動
minfds=1024 ; 可以打開的文件描述符的最小值,默認 1024
minprocs=200 ; 可以打開的進程數的最小值,默認 200
; the below section must remain
in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them
in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; 通過 UNIX socket 連接 supervisord,路徑與 unix_http_server 部分的 file 一致
;serverurl=http://127.0.0.1:9001 ; 通過 HTTP 的方式連接 supervisord
; 包含其他的配置文件
[include]
files = relative/directory/*.ini ; 可以是 *.conf 或 *.ini
|
運行以下命令啟動supervisord進程,可測試supervisord是否安裝成功並執行。
1
|
supervisord -c supervisord.conf
|
查看系統進程中是否多了一個supervisord:
1
|
ps -aux | grep supervisord
|
配置Program
program就是用來配置監控不同的應用程序進程的,推薦每個應用程序單獨寫一個program配置文件,然后在supervisord.conf中通過include加載所有應用程序的配置。
這里拿創建一個celery進程為例,首先在supervisord.conf最后一行寫入:
1
2
3
|
;加載/etc/supervisor/目錄下所有的配置文件
[include]
files = /etc/supervisor/*.conf
|
然后創建/etc/supervisor目錄,並到目錄下創建/etc/supervisor/celery_touchscan.conf文件,寫入:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
;program名稱,隨便寫,但不要重復,是program的唯一標識
[program:celery_touchscan]
;指定運行目錄
directory=/root/TouchScanV2/
;運行目錄下執行命令
command=celery -A scan worker --queue=touchscan --pidfile="./log/pid.txt" --logfile="./log/scan.log" -c 10
;進程名稱
process_name=%(program_name)s_%(process_num)02d
;啟動設置
numprocs=1 ;進程數,注意:(celery進程數量,不是work數量,相當於執行了10個
command命令,而不是在celery中指定-c 為10)
autostart=
true ;當supervisor啟動時,程序將會自動啟動
autorestart=
true ;自動重啟(當work被kill了之后會重新啟動)
;運行程序的用戶
;user=root
;startsecs=1 ;程序重啟時候停留在runing狀態的秒數
;startretries=10 ;啟動失敗時的最多重試次數
;停止信號,默認TERM
;中斷:INT (類似於Ctrl+C)(
kill -INT pid),退出后會將寫文件或日志(推薦)
;終止:TERM (
kill -TERM pid)
;掛起:HUP (
kill -HUP pid),注意與Ctrl+Z/kill -stop pid不同
;從容停止:QUIT (
kill -QUIT pid)
stopsignal=INT
|
重啟supervisord進程:
1
|
supervisorctl -c supervisord.conf reload
|
此時查看系統上的進程,發現創建了一個supervisord守護進程,10個celery的work進程(celery的work進程數量取決於command命令中的-c參數以及配置文件中的numprocs參數,numprocs參數是指運行幾次command命令,而在celery命令行中指定了需要運行的work數量)
說明:此時如果手動kill掉celery的work進程,會發現celery的work進程會被supervisord自動重啟,只有當supervisord守護進程被kill以后,才能真正kill掉celery的work進程。
supervisord命令行操作
啟動supervisord進程
1
|
supervisord -c supervisord.conf
|
關閉supervisord進程
1
|
supervisorctl -c supervisord.conf shutdown
#注意這里將supervisord進程關閉,但通過supervisord啟動的進程沒有關閉
|
重啟supervisord進程
1
|
supervisorctl -c supervisord.conf reload
|
查看進程狀態
1
|
supervisorctl
|
效果如下:
每列分別代表:programe名稱、進程名稱,進程狀態、進程id,運行時間
更多supervisorctl命令
1
2
3
4
5
6
|
$ supervisorctl status
$ supervisorctl stop celery_touchscan
# celery_touchscan是一個program的名稱
$ supervisorctl start celery_touchscan
$ supervisorctl restart celery_touchscan
$ supervisorctl reread
$ supervisorctl update
|
說明:可以直接在系統shell中執行,也可以先執行supervisorctl,進入supervisorctl_shell中執行相應的命令。
針對Python環境
如果項目使用了python的pyenv模塊來設置環境,則supervisord配置文件中需要指定python環境的路徑。其中有兩種方式指定程序使用的Python環境:
- command使用絕對路徑。
- 通過environment配置PYTHONPATH。
使用supervisord注意點
子進程問題
有時候用Supervisor托管的程序還會有子進程,如果只殺死主進程,子進程就可能變成孤兒進程。通過以下這兩項配置來確保所有子進程都能正確停止:
1
2
|
stopasgroup=
true
killasgroup=
true
|
配置更新
每次修改supervisord配置文件后,需要重啟supervisord進程。
后台程序問題
Supervisor只能管理在前台運行的程序,所以如果應用程序有后台運行的選項,需要關閉。
supervisord與定時任務
supervisord主要用來管理進程,而不是調度任務,因此如果有定時任務的需求,跟結合crontab一起使用。當然如果是管理celery服務,可以結合celery自身的定時任務功能,具體可移步:https://thief.one/2017/08/25/1/
supervisord xml-rpc
前面介紹的都是在本地利用supervisord管理進程,那么如何實現在遠處管理服務器上的進程呢?supervisord工具提供了相關的api。首先需要在配置文件中打開相關配置信息:
1
2
3
4
|
[inet_http_server] ; HTTP 服務器,提供 web 管理界面
port=127.0.0.1:9001 ; Web 管理后台運行的 IP 和端口,如果開放到公網,需要注意安全性
username=user ; 登錄管理后台的用戶名
password=123 ; 登錄管理后台的密碼
|
然后啟動supervisord后,可以用web界面管理進程,打開http://127.0.0.1:9001。當然也提供了rpc接口,可供遠程調用,代碼樣例如下:
1
2
3
4
5
6
7
8
9
|
import xmlrpclib
server = xmlrpclib.Server(
'http://user:123@127.0.0.1:9111/RPC2') #連接rpc服務
# print server.system.listMethods() # 查詢api支持的方法
# print server.supervisor.getState() # 獲取supervisord進程狀態
# print server.supervisor.shutdown() # 關閉supervisor,慎用
# print server.supervisor.restart() # 重啟supervisor
print server.supervisor.getProcessInfo(process_name) # 獲取指定進程信息
print server.supervisor.startProcess(process_name) # 啟動指定進程
print server.supervisor.stopProcess(process_name) # 暫停指定進程
|
api操作比較簡單,具體的方法使用文檔可以參考:http://supervisord.org/api.html#xml-rpc
參考
https://pypi.org/project/supervisor/
https://www.jianshu.com/p/9559ab642d88
http://liyangliang.me/posts/2015/06/using-supervisor/