supervisor
使用Python撰寫的行程管理程式supervisor來管理Python程式那是最合適不過了,supervisor基于CS架構,主要有以下兩個組成部分:
- supervisord:supervisord是supervisor的服務端程式,負責啟動子程式,應答客戶端命令,子程式日志記錄,對行程變化發送事件通知等
- supervisorctl: 客戶端命令列工具,可以連接服務器端,進行行程的啟動、關閉、重啟、狀態查看等,重要的一點是,supervisorctl不僅可以連接到本機上的supervisord,還可以連接到遠程的supervisord,當然在本機上面是通過UNIX socket連接的,遠程是通過TCP socket連接的,supervisorctl和supervisord之間的通信,是通過xml_rpc完成的, 相應的配置在[supervisorctl]塊里面
安裝
基于ubuntu16.04,不同linux發行版均可使用包管理器進行安裝,也可以使用原始碼安裝和pip安裝
apt-get install python-setuptools
apt-get install supervisor
pip安裝方法
pip install supervisor
當前最新版本3.3.3,supervisord.conf 和supervisord.d檔案夾已自動生成在/etc/supervisor/目錄下,可以使用echo_supervisord_conf命令將配置資訊重定向到制定目錄,比如/etc
echo_supervisord_conf > /etc/supervisor/supervisord.conf
服務端啟動
supervisord -c /etc/supervisor/supervisord.conf
查看supervisord是否在運行
ps aux | grep supervisord
supervisord.conf詳解
使用echo_supervisord_conf查看supervisord.conf可選的配置項:
echo_supervisord_conf help
詳情如下
; Sample supervisor config file.
;
; For more information on the config file, please see:
; http://supervisord.org/configuration.html
;
; Notes:
; - Shell expansion ("~" or "$HOME") is not supported. Environment
; variables can be expanded using this syntax: "%(ENV_HOME)s".
; - Comments must have a leading space: "a=b ;comment" not "a=b;comment".
[unix_http_server]
file=/tmp/supervisor.sock ; socket 檔案路徑
;chmod=0700 ; socket 檔案 模式 (默認 0700)
;chown=nobody:nogroup ; socket file uid:gid owner
;username=user ; 使用supervisorctl連接的用戶,默認沒有用戶
;password=123 ; 使用supervisorctl連接的用戶密碼,默認沒有密碼
;[inet_http_server] ; Web Server和遠程的supervisorctl 配置塊(默認關閉)
;port=127.0.0.1:9001 ; 監聽的地址和埠
;username=user ; 登錄用戶,默認沒有用戶
;password=123 ; 登錄密碼,默認沒有密碼
[supervisord]
logfile=/tmp/supervisord.log ; supervisord行程日志路徑
logfile_maxbytes=50MB ; supervisord行程單個日志檔案大小,默認為50M
logfile_backups=10 ; 日志檔案個數,默認為10個
loglevel=info ; 日志級別,默認為info,還支持debug,warn,trace)
pidfile=/tmp/supervisord.pid ; supervisord的pid檔案路徑,
nodaemon=false ; 如果是true,supervisord行程將在前臺運行 默認為false(后臺運行)
minfds=1024 ; 這個是最少系統空閑的檔案描述符,低于這個值supervisor將不會啟動
minprocs=200 ; 最小可用的行程描述符,低于這個值supervisor也將不會正常啟動
;umask=022 ; 行程創建檔案的掩碼 (默認 022)
;user=chrism ; user引數指定的用戶也可以對supervisord進行管理
;identifier=supervisor ; supervisord的識別符號,默認supervisor
;directory=/tmp ; 當supervisord以守護行程運行的時候,啟動supervisord行程之前,會先切換到這個目錄
;nocleanup=true ; false的時候 supervisord行程啟動的時候 會在把以前子行程產生的臨時檔案清除掉(true不清除)
;childlogdir=/tmp ; 當子行程日志路徑為AUTO的時候,子行程日志檔案的存放路徑 (默認 $TMP)
;environment=KEY="value" ; 這個是用來設定環境變數的,supervisord在linux中啟動默認繼承了linux的 環境變數,在這里可以設定supervisord行程特有的其他環境變數supervisord啟動子行程時,子行程會拷貝父行程的記憶體空間內容, 所以設定的這些環境變數也會被子行程繼承 (默認不設定)
;strip_ansi=false ; 默認為falsh,如果設定為true,會清除子行程日志中的所有ANSI(\n,\t) 序列
; 這個選項是給XML_RPC用的,如果想使用supervisord或者web server 必須要開啟
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; supervisorctl本地連接supervisord,使用本地UNIX socket
;serverurl=http://127.0.0.1:9001 ; supervisorctl遠程連接supervisord的時候,用到的地址和埠
;username=chris ; 連接登錄的用戶名,需要和http_username一致
;password=123 ; 連接登錄的密碼,需要和http_password一致
;prompt=mysupervisor ; 輸入用戶名密碼時候的提示符 默認:mysupervisor
;history_file=~/.sc_history ; 指定歷史命令的檔案
;[program:theprogramname] ; 指定program配置
;command=/bin/cat ; 要執行的行程 可帶引數 $1 $2 $3 注意!! 執行的行程不能是守護行程 ! !
;process_name=%(program_name)s ; numprocs引數為1時,就不用管這個引數 默認值%(program_name)s也就是上面的那個program冒號后面的名字
;numprocs=1 ; 啟動行程的數目,當不為1時,就是行程池的概念,默認為1
;directory=/tmp ; 行程運行前,會前切換到這個目錄
;umask=022 ; 行程掩碼 (default None)
;priority=999 ; 子行程啟動關閉優先級,優先級低的,最先啟動,關閉的時候最后關閉 (default 999)
;autostart=true ; 設定為true 子行程將在supervisord啟動后被自動啟動,默認為true
;startsecs=1 ; 設定子行程啟動多少秒之后,此時狀態如果是running,則我們認為啟動成功
;startretries=3 ; 行程啟動失敗后,最大嘗試啟動的次數 當超過3次后,supervisor將把此行程的狀態置為FAIL
;autorestart=unexpected ; 設定子行程掛掉后自動重啟的情況,有三個選項,false,unexpected和true,如果為false的時候,無論什么情況下,都不會被重新啟動,如果為unexpected,只有當行程的退出碼不在上面的exitcodes里面定義的退出碼的時候,>才會被自動重啟,當為true的時候,只要子行程掛掉,將會被無條件的重啟,默認為unexpected
;exitcodes=0,2 ; 注意和上面的的autorestart=unexpected對應 exitcodes里面的定義的退出碼是expected的,
;stopsignal=QUIT ; 行程停止信號,可以為TERM, HUP, INT, QUIT, KILL, USR1, or USR2等信號 默認為TERM 當用設定的信號去殺掉行程,退出碼會被認為是expected
;stopwaitsecs=10 ; 這個是當我們向子行程發送stopsignal信號后,到系統回傳資訊給supervisord,所等待的最大時間, 超過這個時間,supervisord會向該子行程發送一個強制kill的信號(默認10秒)
;stopasgroup=false ; 這個東西主要用于,supervisord管理的子行程,這個子行程本身還有子行程 那么我們如果僅僅干掉supervisord的子行程的話,子行程的子行程有可能會變成孤兒行程 所以咱們可以設定這個選項,把整個該子行程的整個行程組都干掉 設定為true的話,一般killasgroup也會被設定為true 該選項發送的是stop信號(def false)
;killasgroup=false ; 這個和上面的stopasgroup類似,不過發送的是kill信號(def false)
;user=chrism ; 如果supervisord是root啟動,我們在這里設定這個非root用戶,可以用來管理該program 默認不設定
;redirect_stderr=true ; 為true,則stderr的日志會被寫入stdout日志檔案中 (default false)
;stdout_logfile=/a/path ; 子行程的stdout的日志路徑,可以指定路徑,AUTO,none等三個選項 設定為none的話,將沒有日志產生,設定為AUTO的話,將隨機找一個地方成日志檔案,而且當supervisord重新啟動的時候,以前的日志檔案會被清空,當 redirect_stderr=true的時候,sterr也會寫進這個日志檔案
;stdout_logfile_maxbytes=1MB ; 日志檔案最大大小,和[supervisord]中定義的一樣 (default 50MB)
;stdout_logfile_backups=10 ; 和[supervisord]定義的一樣 (0 means none, default 10)
;stdout_capture_maxbytes=1MB ; 這個東西是設定capture管道的大小,當值不為0的時候,子行程可以從stdout發送資訊,而supervisor可以根據資訊,發送相應的event (default 0)
;stdout_events_enabled=false ; 為ture的時候,當子行程由stdout向檔案描述符中寫日志的時候,將觸發supervisord發送PROCESS_LOG_STDOUT型別的event(default false)
;stderr_logfile=/a/path ; 設定stderr寫的日志路徑,當redirect_stderr=true,這個就不用設定了,設定了也是白搭,因為它會被寫入stdout_logfile的同一個檔案中 default AUTO(隨便找個地存,supervisord重啟被清空)
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A="1",B="2" ; 這個是該子行程的環境變數,和別的子行程是不共享的
;serverurl=AUTO ; override serverurl computation (childutils)
;[eventlistener:theeventlistenername] ; eventlistener其實和program的地位是一樣的,也是suopervisor啟動的子行程,不過它干的活是訂閱supervisord發送的event,他的名字就叫listener了,我們可以在listener里面做一系列處理,比如報警....
;command=/bin/eventlistener ; 和上面的program一樣,表示listener的可執行檔案的路徑
;process_name=%(program_name)s ; 這個也一樣,行程名,當下面的numprocs為多個的時候,才需要,否則默認就OK了
;numprocs=1 ; 相同的listener啟動的個數,默認1
;events=EVENT ; event event事件的型別,也就是說,只有寫在這個地方的事件型別,才會被發送
;buffer_size=10 ; event佇列快取大小 (default 10)
;directory=/tmp ; 行程執行前,會切換到這個目錄下執行 (def no cwd)
;umask=022 ; umask for process (default None)
;priority=-1 ; 啟動優先級 (default -1)
;autostart=true ; supervisord啟動時一起啟動 (default: true)
;startsecs=1 ; 設定子行程啟動多少秒之后,此時狀態如果是running,則我們認為啟動成功了 (def. 1)
;startretries=3 ; 失敗最大嘗試次數 (default 3)
;autorestart=unexpected ; 和program一樣 (def: unexpected)
;exitcodes=0,2 ; 'expected' exit codes used with autorestart (default 0,2)
;stopsignal=QUIT ; signal used to kill process (default TERM)
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false ; send stop signal to the UNIX process group (default false)
;killasgroup=false ; SIGKILL the UNIX process group (def false)
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=false ; redirect_stderr=true is not allowed for eventlisteners
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A="1",B="2" ; process environment additions
;serverurl=AUTO ; override serverurl computation (childutils)
;[group:thegroupname] ; 給programs分組,劃分到組里面的program,我們就不用一個一個去操作了 我們可以對組名進行統一的操作, 注意:program被劃分到組里面之后,就相當于原來的配置從supervisor的組態檔里消失了supervisor只會對組進行管理,而不再會對組里面的單個program進行管理了
;programs=progname1,progname2 ; 組成員,用逗號分開
;priority=999 ; 優先級,相對于組和組之間 (default 999)
;[include] ;包含的程式組態檔
;files = relative/directory/*.ini
提取supervisord.conf模板
采用supervisord.conf和program.conf分離的方式進行本機行程管理,從默認配置中抽取出常用的supervisord模板
; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
[inet_http_server] ; inet (TCP) server disabled by default
port=127.0.0.1:9001 ; (ip_address:port specifier, *:port for all iface)
username=erow ; (default is no username (open server))
password=j ; (default is no password (open server))
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
loglevel=debug ; (log level;default info; others: debug,warn,trace)
logfile_maxbytes=10MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
[include]
files = /etc/supervisor/conf.d/*.ini
模板抽取基于以下考慮
- 必填選項不可少
- 服務端支持本地supervisorctl客戶端連接也支持遠程連接
- 測驗環境日志級別設定為debug,生產環境日志級別設定為info,修改loglevel欄位即可
- 日志檔案大小和個數需要參考服務端所在機器的磁盤大小,會產生stderr和stdout兩種日志
- pid檔案和log檔案都不建議存放在/tmp下面,容易被誤洗掉,因此放在var目錄下
提取program.conf模板
從默認配置中抽取出常用的program模板
[program:concurrency_statistician]
directory = /root/qk_python/data/statistic/concurrency_statistician
command = python concurrency_statistician.py
autostart = true
startsecs = 5
autorestart = true
startretries = 3
user = root
如果單獨調整program日志大小和個數,則加入stdout和stderr四個引數,新的組態檔如下
[program:concurrency_statistician]
directory = /root/qk_python/data/statistic/concurrency_statistician
command = python concurrency_statistician.py
autostart = true
startsecs = 5
autorestart = true
startretries = 3
user = root
stdout_logfile_maxbytes = 10MB
stdout_logfile_backups = 10
stderr_logfile_maxbytes = 10MB
stderr_logfile_backups = 10
一般情況下,不需要指定日志檔案名稱,默認的日志檔案名稱組成為
- 程式名稱+日志型別(stdout和stderr)+ supervisor+行程號+日志編號
檔案名稱示例:concurrency_statistician-stderr---supervisor-OpZ5di.log.2
需要注意:supervisor服務端程式supervisord重新啟動之后,會產生新的pid,因此日志只會在新的行程日志中產生,老的子行程日志不會被洗掉,因此如果需要重新啟動supervisord,則需要注意是否要保留老行程日志,以免超過磁盤大小,
一般情況下,生產環境中不會經常重啟supervisord
常用supervisorctl命令
可以進入 supervisorctl 的 shell 界面,也可以直接在 bash 終端運行
# 停止某一個行程,program_name 為 [program:x] 里的 x
supervisorctl stop program_name
# 啟動某個行程
supervisorctl start program_name
# 重啟某個行程
supervisorctl restart program_name
# 停止全部行程,注:start、restart、stop 都不會載入最新的組態檔
supervisorctl stop all
# 載入最新的組態檔,停止原有行程并按新的配置啟動、管理所有行程
supervisorctl reload
# 根據最新的組態檔,啟動新配置或有改動的行程,配置沒有改動的行程不會受影響而重啟
supervisorctl update
關于program groups的命令使用較少暫不介紹
參考資料:
- supervisor 官方檔案
- 小強齋太-Supervisor簡介、安裝、配置
- 使用supervisor管理行程
- 廖雪峰-Linux后臺行程管理利器:supervisor
- 烏龜運維-Supervisor 安裝及配置
- oschina-SUPERVISOR行程管理器配置指南
記得幫我點贊哦!
精心整理了計算機各個方向的從入門、進階、實戰的視頻課程和電子書,按照目錄合理分類,總能找到你需要的學習資料,還在等什么?快去關注下載吧!!!

念念不忘,必有回響,小伙伴們幫我點個贊吧,非常感謝,
我是職場亮哥,YY高級軟體工程師、四年作業經驗,拒絕咸魚爭當龍頭的斜杠程式員,
聽我說,進步多,程式人生一把梭
如果有幸能幫到你,請幫我點個【贊】,給個關注,如果能順帶評論給個鼓勵,將不勝感激,
職場亮哥文章串列:更多文章

本人所有文章、回答都與著作權保護平臺有合作,著作權歸職場亮哥所有,未經授權,轉載必究!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/231309.html
標籤:Python
下一篇:安裝pyspider出現的問題
