欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Python 的進(jìn)程管理工具supervisor使用指南

 更新時(shí)間:2016年09月18日 09:09:14   作者:restran  
Supervisor 是基于 Python 的進(jìn)程管理工具,可以輕松管理一些需要以守護(hù)進(jìn)程方式執(zhí)行的程序,也就是后臺(tái)任務(wù),例如用來(lái)啟動(dòng)和管理基于 Tornado 寫的 Web 程序。

Supervisor 是基于 Python 的進(jìn)程管理工具,只能運(yùn)行在 Unix-Like 的系統(tǒng)上,也就是無(wú)法運(yùn)行在 Windows 上。Supervisor 官方版目前只能運(yùn)行在 Python 2.4 以上版本,但是還無(wú)法運(yùn)行在 Python 3 上,不過(guò)已經(jīng)有一個(gè) Python 3 的移植版 supervisor-py3k

什么情況下我們需要進(jìn)程管理呢?就是執(zhí)行一些需要以守護(hù)進(jìn)程方式執(zhí)行的程序,比如一個(gè)后臺(tái)任務(wù),我最常用的是用來(lái)啟動(dòng)和管理基于 Tornado 寫的 Web 程序。

除此之外,Supervisor 還能很友好的管理程序在命令行上輸出的日志,可以將日志重定向到自定義的日志文件中,還能按文件大小對(duì)日志進(jìn)行分割。

Supervisor 有兩個(gè)主要的組成部分:

  1. supervisord,運(yùn)行 Supervisor 時(shí)會(huì)啟動(dòng)一個(gè)進(jìn)程 supervisord,它負(fù)責(zé)啟動(dòng)所管理的進(jìn)程,并將所管理的進(jìn)程作為自己的子進(jìn)程來(lái)啟動(dòng),而且可以在所管理的進(jìn)程出現(xiàn)崩潰時(shí)自動(dòng)重啟。
  2. supervisorctl,是命令行管理工具,可以用來(lái)執(zhí)行 stop、start、restart 等命令,來(lái)對(duì)這些子進(jìn)程進(jìn)行管理。

安裝

sudo pip install supervisor

創(chuàng)建配置文件

echo_supervisord_conf > /etc/supervisord.conf

如果出現(xiàn)沒有權(quán)限的問(wèn)題,可以使用這條命令

sudo su - root -c "echo_supervisord_conf > /etc/supervisord.conf"

配置文件說(shuō)明

想要了解怎么配置需要管理的進(jìn)程,只要打開 supervisord.conf 就可以了,里面有很詳細(xì)的注釋信息。

打開配置文件

vim /etc/supervisord.conf

默認(rèn)的配置文件是下面這樣的,但是這里有個(gè)坑需要注意,supervisord.pid 以及 supervisor.sock 是放在 /tmp 目錄下,但是 /tmp 目錄是存放臨時(shí)文件,里面的文件是會(huì)被 Linux 系統(tǒng)刪除的,一旦這些文件丟失,就無(wú)法再通過(guò) supervisorctl 來(lái)執(zhí)行 restart 和 stop 命令了,將只會(huì)得到 unix:///tmp/supervisor.sock 不存在的錯(cuò)誤 。

[unix_http_server]
;file=/tmp/supervisor.sock  ; (the path to the socket file)
;修改為 /var/run 目錄,避免被系統(tǒng)刪除
file=/var/run/supervisor.sock  ; (the path to the socket file)
;chmod=0700         ; socket file mode (default 0700)
;chown=nobody:nogroup    ; socket file uid:gid owner
;username=user       ; (default is no username (open server))
;password=123        ; (default is no password (open server))

;[inet_http_server]     ; inet (TCP) server disabled by default
;port=127.0.0.1:9001    ; (ip_address:port specifier, *:port for ;all iface)
;username=user       ; (default is no username (open server))
;password=123        ; (default is no password (open server))
...

[supervisord]
;logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
;修改為 /var/log 目錄,避免被系統(tǒng)刪除
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB    ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10      ; (num of main logfile rotation backups;default 10)
loglevel=info        ; (log level;default info; others: debug,warn,trace)
;pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
;修改為 /var/run 目錄,避免被系統(tǒng)刪除
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
...
;設(shè)置啟動(dòng)supervisord的用戶,一般情況下不要輕易用root用戶來(lái)啟動(dòng),除非你真的確定要這么做
;user=chrism         ; (default is current user, required if root)
...

[supervisorctl]
; 必須和'unix_http_server'里面的設(shè)定匹配
;serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
;修改為 /var/run 目錄,避免被系統(tǒng)刪除
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris       ; should be same as http_username if set
;password=123        ; should be same as http_password if set
...

默認(rèn)情況下,進(jìn)程的日志文件達(dá)到50MB時(shí),將進(jìn)行分割,最多保留10個(gè)文件,當(dāng)然這些配置也可以對(duì)每個(gè)進(jìn)程單獨(dú)配置。

權(quán)限問(wèn)題

設(shè)置好配置文件后,應(yīng)先創(chuàng)建上述配置文件中新增的文件夾。如果指定了啟動(dòng)用戶 user,這里以 oxygen 為例,那么應(yīng)注意相關(guān)文件的權(quán)限問(wèn)題,包括日志文件,否則會(huì)出現(xiàn)沒有權(quán)限的錯(cuò)誤。例如設(shè)置了啟動(dòng)用戶 oxygen,然后啟動(dòng) supervisord 出現(xiàn)錯(cuò)誤

Error: Cannot open an HTTP server: socket.error reported errno.EACCES (13)

就是由于上面的配置文件中 /var/run 文件夾,沒有授予啟動(dòng) supervisord 的用戶 oxygen 的寫權(quán)限。/var/run 文件夾實(shí)際上是鏈接到 /run,因此我們修改 /run 的權(quán)限。

sudo chmod 777 /run

這樣有點(diǎn)簡(jiǎn)單粗暴,也可以考慮把上述配置文件中 .sock,.pid 等文件修改到其他文件夾中,并確保有相應(yīng)的權(quán)限即可。一般情況下,我們可以用 root 用戶啟動(dòng) supervisord 進(jìn)程,然后在其所管理的進(jìn)程中,再具體指定需要以那個(gè)用戶啟動(dòng)這些進(jìn)程。

使用瀏覽器來(lái)管理

supervisor 同時(shí)提供了通過(guò)瀏覽器來(lái)管理進(jìn)程的方法,只需要注釋掉如下幾行就可以了。

;[inet_http_server]     ; inet (TCP) server disabled by default
;port=127.0.0.1:9001    ; (ip_address:port specifier, *:port for ;all iface)
;username=user       ; (default is no username (open server))
;password=123        ; (default is no password (open server))

[supervisorctl]
...
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris       ; should be same as http_username if set
;password=123        ; should be same as http_password if set

 

使用 include

在配置文件的最后,有一個(gè) [include] 的配置項(xiàng),跟 Nginx 一樣,可以 include 某個(gè)文件夾下的所有配置文件,這樣我們就可以為每個(gè)進(jìn)程或相關(guān)的幾個(gè)進(jìn)程的配置單獨(dú)寫成一個(gè)文件。

[include]
files = /etc/supervisord.d/*.ini


進(jìn)程的配置樣例

一個(gè)簡(jiǎn)單的例子如下

; 設(shè)置進(jìn)程的名稱,使用 supervisorctl 來(lái)管理進(jìn)程時(shí)需要使用該進(jìn)程名
[program:your_program_name] 
command=python server.py --port=9000
;numprocs=1         ; 默認(rèn)為1
;process_name=%(program_name)s  ; 默認(rèn)為 %(program_name)s,即 [program:x] 中的 x
directory=/home/python/tornado_server ; 執(zhí)行 command 之前,先切換到工作目錄
user=oxygen         ; 使用 oxygen 用戶來(lái)啟動(dòng)該進(jìn)程
; 程序崩潰時(shí)自動(dòng)重啟,重啟次數(shù)是有限制的,默認(rèn)為3次
autorestart=true      
redirect_stderr=true    ; 重定向輸出的日志
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

設(shè)置日志級(jí)別

loglevel 指定了日志的級(jí)別,用 Python 的 print 語(yǔ)句輸出的日志是不會(huì)被記錄到日志文件中的,需要搭配 Python 的 logging 模塊來(lái)輸出有指定級(jí)別的日志。

多個(gè)進(jìn)程

按照官方文檔的定義,一個(gè) [program:x] 實(shí)際上是表示一組相同特征或同類的進(jìn)程組,也就是說(shuō)一個(gè) [program:x] 可以啟動(dòng)多個(gè)進(jìn)程。這組進(jìn)程的成員是通過(guò) numprocs 和 process_name 這兩個(gè)參數(shù)來(lái)確定的,這句話什么意思呢,我們來(lái)看這個(gè)例子。

; 設(shè)置進(jìn)程的名稱,使用 supervisorctl 來(lái)管理進(jìn)程時(shí)需要使用該進(jìn)程名
[program:foo] 
; 可以在 command 這里用 python 表達(dá)式傳遞不同的參數(shù)給每個(gè)進(jìn)程
command=python server.py --port=90%(process_num)02d
directory=/home/python/tornado_server ; 執(zhí)行 command 之前,先切換到工作目錄
; 若 numprocs 不為1,process_name 的表達(dá)式中一定要包含 process_num 來(lái)區(qū)分不同的進(jìn)程
numprocs=2          
process_name=%(program_name)s_%(process_num)02d; 
user=oxygen         ; 使用 oxygen 用戶來(lái)啟動(dòng)該進(jìn)程
autorestart=true      ; 程序崩潰時(shí)自動(dòng)重啟
redirect_stderr=true    ; 重定向輸出的日志
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

上面這個(gè)例子會(huì)啟動(dòng)兩個(gè)進(jìn)程,process_name 分別為 foo:foo_01 和 foo:foo_02。通過(guò)這樣一種方式,就可以用一個(gè) [program:x] 配置項(xiàng),來(lái)啟動(dòng)一組非常類似的進(jìn)程。

再介紹兩個(gè)配置項(xiàng) stopasgroup 和 killasgroup

; 默認(rèn)為 false,如果設(shè)置為 true,當(dāng)進(jìn)程收到 stop 信號(hào)時(shí),會(huì)自動(dòng)將該信號(hào)發(fā)給該進(jìn)程的子進(jìn)程。如果這個(gè)配置項(xiàng)為 true,那么也隱含 killasgroup 為 true。例如在 Debug 模式使用 Flask 時(shí),F(xiàn)lask 不會(huì)將接收到的 stop 信號(hào)也傳遞給它的子進(jìn)程,因此就需要設(shè)置這個(gè)配置項(xiàng)。

stopasgroup=false       ; send stop signal to the UNIX process 

; 默認(rèn)為 false,如果設(shè)置為 true,當(dāng)進(jìn)程收到 kill 信號(hào)時(shí),會(huì)自動(dòng)將該信號(hào)發(fā)給該進(jìn)程的子進(jìn)程。如果這個(gè)程序使用了 python 的 multiprocessing 時(shí),就能自動(dòng)停止它的子線程。
killasgroup=false       ; SIGKILL the UNIX process group (def false)

更詳細(xì)的配置例子,可以參考如下,官方文檔在這里

;[program:theprogramname]
;command=/bin/cat       ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1          ; number of processes copies to start (def 1)
;directory=/tmp        ; directory to cwd to before exec (def no cwd)
;umask=022           ; umask for process (default None)
;priority=999         ; the relative start priority (default 999)
;autostart=true        ; start at supervisord start (default: true)
;autorestart=unexpected    ; whether/when to restart (default: unexpected)
;startsecs=1          ; number of secs prog must stay running (def. 1)
;startretries=3        ; max # of serial start failures (default 3)
;exitcodes=0,2         ; 'expected' exit codes for process (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=true     ; redirect proc stderr to stdout (default false)
;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_capture_maxbytes=1MB  ; number of bytes in 'capturemode' (default 0)
;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_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"    ; process environment additions (def no adds)
;serverurl=AUTO        ; override serverurl computation (childutils)

將多個(gè)進(jìn)程按組管理

Supervisor 同時(shí)還提供了另外一種進(jìn)程組的管理方式,通過(guò)這種方式,可以使用 supervisorctl 命令來(lái)管理一組進(jìn)程。跟 [program:x] 的進(jìn)程組不同的是,這里的進(jìn)程是一個(gè)個(gè)的 [program:x] 。

[group:thegroupname]
programs=progname1,progname2 ; each refers to 'x' in [program:x] definitions
priority=999         ; the relative start priority (default 999)

當(dāng)添加了上述配置后,progname1 和 progname2 的進(jìn)程名就會(huì)變成 thegroupname:progname1 和 thegroupname:progname2 以后就要用這個(gè)名字來(lái)管理進(jìn)程了,而不是之前的 progname1。

以后執(zhí)行 supervisorctl stop thegroupname: 就能同時(shí)結(jié)束 progname1 和 progname2,執(zhí)行 supervisorctl stop thegroupname:progname1 就能結(jié)束 progname1。supervisorctl 的命令我們稍后介紹。

啟動(dòng) supervisord

執(zhí)行 supervisord 命令,將會(huì)啟動(dòng) supervisord 進(jìn)程,同時(shí)我們?cè)谂渲梦募性O(shè)置的進(jìn)程也會(huì)相應(yīng)啟動(dòng)。

# 使用默認(rèn)的配置文件 /etc/supervisord.conf
supervisord
# 明確指定配置文件
supervisord -c /etc/supervisord.conf
# 使用 user 用戶啟動(dòng) supervisord
supervisord -u user

更多參數(shù)請(qǐng)參考文檔

supervisorctl 命令介紹

# 停止某一個(gè)進(jìn)程,program_name 為 [program:x] 里的 x
supervisorctl stop program_name
# 啟動(dòng)某個(gè)進(jìn)程
supervisorctl start program_name
# 重啟某個(gè)進(jìn)程
supervisorctl restart program_name
# 結(jié)束所有屬于名為 groupworker 這個(gè)分組的進(jìn)程 (start,restart 同理)
supervisorctl stop groupworker:
# 結(jié)束 groupworker:name1 這個(gè)進(jìn)程 (start,restart 同理)
supervisorctl stop groupworker:name1
# 停止全部進(jìn)程,注:start、restart、stop 都不會(huì)載入最新的配置文件
supervisorctl stop all
# 載入最新的配置文件,停止原有進(jìn)程并按新的配置啟動(dòng)、管理所有進(jìn)程
supervisorctl reload
# 根據(jù)最新的配置文件,啟動(dòng)新配置或有改動(dòng)的進(jìn)程,配置沒有改動(dòng)的進(jìn)程不會(huì)受影響而重啟
supervisorctl update

注意:顯示用 stop 停止掉的進(jìn)程,用 reload 或者 update 都不會(huì)自動(dòng)重啟。也可以參考這里

開機(jī)自動(dòng)啟動(dòng) Supervisord

Supervisord 默認(rèn)情況下并沒有被安裝成服務(wù),它本身也是一個(gè)進(jìn)程。官方已經(jīng)給出了腳本可以將 Supervisord 安裝成服務(wù),可以參考這里查看各種操作系統(tǒng)的安裝腳本,但是我用官方這里給的 Ubuntu 腳本卻無(wú)法運(yùn)行。

安裝方法可以參考 serverfault 上的回答。

比如我是 Ubuntu 系統(tǒng),可以這么安裝,這里選擇了另外一個(gè)腳本

# 下載腳本
sudo su - root -c "sudo curl https://gist.githubusercontent.com/howthebodyworks/176149/raw/d60b505a585dda836fadecca8f6b03884153196b/supervisord.sh > /etc/init.d/supervisord"
# 設(shè)置該腳本為可以執(zhí)行
sudo chmod +x /etc/init.d/supervisord
# 設(shè)置為開機(jī)自動(dòng)運(yùn)行
sudo update-rc.d supervisord defaults
# 試一下,是否工作正常
service supervisord stop
service supervisord start

注意:這個(gè)腳本下載下來(lái)后,還需檢查一下與我們的配置是否相符合,比如默認(rèn)的配置文件路徑,pid 文件路徑等,如果存在不同則需要進(jìn)行一些修改。

其實(shí)還有一個(gè)簡(jiǎn)單的方法,因?yàn)?Linux 在啟動(dòng)的時(shí)候會(huì)執(zhí)行 /etc/rc.local 里面的腳本,所以只要在這里添加執(zhí)行命令就可以

# 如果是 Ubuntu 添加以下內(nèi)容
/usr/local/bin/supervisord -c /etc/supervisord.conf

# 如果是 Centos 添加以下內(nèi)容
/usr/bin/supervisord -c /etc/supervisord.conf

以上內(nèi)容需要添加在 exit 命令前,而且由于在執(zhí)行 rc.local 腳本時(shí),PATH 環(huán)境變量未全部初始化,因此命令需要使用絕對(duì)路徑。

在添加前,先在終端測(cè)試一下命令是否能正常執(zhí)行,如果找不到 supervisord,可以用如下命令找到

sudo find / -name supervisord

相關(guān)文章

  • Django框架模板語(yǔ)言實(shí)例小結(jié)【變量,標(biāo)簽,過(guò)濾器,繼承,html轉(zhuǎn)義】

    Django框架模板語(yǔ)言實(shí)例小結(jié)【變量,標(biāo)簽,過(guò)濾器,繼承,html轉(zhuǎn)義】

    這篇文章主要介紹了Django框架模板語(yǔ)言,結(jié)合實(shí)例形式總結(jié)分析了Django框架中變量,標(biāo)簽,過(guò)濾器,繼承,html轉(zhuǎn)義等相關(guān)模板語(yǔ)言操作技巧,需要的朋友可以參考下
    2019-05-05
  • python如何統(tǒng)計(jì)代碼運(yùn)行的時(shí)長(zhǎng)

    python如何統(tǒng)計(jì)代碼運(yùn)行的時(shí)長(zhǎng)

    這篇文章主要介紹了python如何統(tǒng)計(jì)代碼運(yùn)行的時(shí)長(zhǎng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • Python探索之pLSA實(shí)現(xiàn)代碼

    Python探索之pLSA實(shí)現(xiàn)代碼

    偶然看到了pLSA模型這個(gè)東東,不懂,于是找了找資料,這里分享給大家一段代碼,幫助理解吧。不好的地方還請(qǐng)多多指教。
    2017-10-10
  • 如何使用yolov5輸出檢測(cè)到的目標(biāo)坐標(biāo)信息

    如何使用yolov5輸出檢測(cè)到的目標(biāo)坐標(biāo)信息

    YOLOv5是一系列在 COCO 數(shù)據(jù)集上預(yù)訓(xùn)練的對(duì)象檢測(cè)架構(gòu)和模型,下面這篇文章主要給大家介紹了關(guān)于如何使用yolov5輸出檢測(cè)到的目標(biāo)坐標(biāo)信息的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • 對(duì)numpy中的transpose和swapaxes函數(shù)詳解

    對(duì)numpy中的transpose和swapaxes函數(shù)詳解

    今天小編就為大家分享一篇對(duì)numpy中的transpose和swapaxes函數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 詳解Python中的偏函數(shù)(Partial Functions)

    詳解Python中的偏函數(shù)(Partial Functions)

    Python中的偏函數(shù)是來(lái)自函數(shù)式編程的一個(gè)強(qiáng)大工具,它的主要目標(biāo)是減少函數(shù)調(diào)用的復(fù)雜性這個(gè)概念可能起初看起來(lái)有點(diǎn)困難理解,但一旦你明白了它的工作方式,它可能會(huì)成為你的編程工具箱中的重要組成部分,文中有相關(guān)的代碼介紹,需要的朋友可以參考下
    2023-06-06
  • 如何利用Matlab制作一款真正的拼圖小游戲

    如何利用Matlab制作一款真正的拼圖小游戲

    這篇文章主要給大家介紹了關(guān)于如何利用Matlab制作一款真正的拼圖小游戲的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 關(guān)于AnacondaNavigator?Jupyter?Notebook更換Python內(nèi)核的問(wèn)題

    關(guān)于AnacondaNavigator?Jupyter?Notebook更換Python內(nèi)核的問(wèn)題

    因?yàn)樾掳惭b的Anaconda?Navigator默認(rèn)安裝了一個(gè)Python,Jupyter?Notebook默認(rèn)使用的內(nèi)核就是這個(gè)Python,跟我系統(tǒng)安裝好的Python沖突了,下面小編給大家介紹AnacondaNavigator?Jupyter?Notebook更換Python內(nèi)核的問(wèn)題,需要的朋友可以參考下
    2022-02-02
  • Python處理缺失值的8種不同方法實(shí)例

    Python處理缺失值的8種不同方法實(shí)例

    缺失值是指粗糙數(shù)據(jù)中由于缺少信息而造成的數(shù)據(jù)的聚類、分組、刪失或截?cái)?下面這篇文章主要給大家介紹了關(guān)于Python處理缺失值的8種不同方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Python用UUID庫(kù)生成唯一ID的方法示例

    Python用UUID庫(kù)生成唯一ID的方法示例

    在C#中很容易生成一組唯一碼,最常用的是結(jié)構(gòu)體GUID的NewGuid()實(shí)例。如果C#運(yùn)行Guid.NewGuid();將會(huì)得到據(jù)說(shuō)世界唯一的號(hào)碼,形如:887687be-00cf-4dca-8fe4-7c4fc19b9ecc 。最近看了一下Python的相關(guān)模塊,也發(fā)現(xiàn)了一個(gè)模塊uuid。下面來(lái)看看詳細(xì)的介紹與使用示例吧。
    2016-12-12

最新評(píng)論