Linux程序管理工具之Supervisor的使用
阿新 • • 發佈:2020-09-10
Supervisor 的使用
一 Supervisor介紹
Supervisor (http://supervisord.org) 是一個用 [Python] 寫的程序管理工具,可以很方便的用來啟動、重啟、關閉程序(不僅僅是 Python 程序)。除了對單個程序的控制,還可以同時啟動、關閉多個程序,比如很不幸的伺服器出問題導致所有應用程式都被殺死,此時可以用 supervisor 同時啟動所有應用程式而不是一個一個地敲命令啟動
二 安裝
2.1 安裝方式
# 可以通過apt-get、yum安裝,既然Supervisor是基於python編寫的,那我們就用pip安裝好了 # 1 配置好yum源後,可以直接安裝 yum install supervisor #2 Debian/Ubuntu可通過apt安裝 apt-get install supervisor # 3 pip安裝 sudo yum install python-setuptools-devel pip install supervisor # 4 easy_install安裝 sudo yum install python-setuptools-devel easy_install supervisor
2.2 驗證
# 1 安裝完成後,會在 /usr/bin 下加入三個命令: [root@lqz bin]# ls |grep super echo_supervisord_conf # 生成一個配置檔案示例 supervisorctl # 服務端 supervisord # 客戶端 # 2 安裝完成後,會在 /etc 下建立一個 supervisord.d目錄用於存放supervisor的配置檔案, # 還有一個supervisord.conf配置檔案(如果沒有使用命令: echo_supervisord_conf > /etc/supervisord.conf 生成) [root@lqz etc]# ls |grep super supervisord.conf supervisord.d # 3 方便起見,把supervisor伺服器相關的配置寫入supervisord.conf中,把監控各個程序的配置,按照程序名存在 supervisord.conf 目錄下。(這個可以在supervisord.conf中的[include]部分下配置)
2.3 配置
# 1 修改配置檔案 vim supervisord.conf # 2 最後一行改為(;表示註釋),這樣配置檔案可以寫到supervisord.d目錄下一xx.ini命名 [include] files = supervisord.d/*.ini # 3 簡單說明: [unix_http_server] 配置socket連線部分 [supervisord] 配置supervisor伺服器部分 [supervisorctl] 配置supervisor客戶端部分 [inet_http_server] 配置web管理介面 [include] 配置需要引入的其他配置
2.4 配置詳情(瞭解)
[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
2.5 啟動、停止、重啟
# 1 啟動supervisord
supervisord -c /etc/supervisord.conf 或 supervisord
# 2 停止supervisord
supervisorctl shutdown
# 3 重新載入配置檔案
supervisorctl reload
# 4 注意:如果配置了密碼(使用如下命令)
supervisorctl -u user -p 123 reload
三 program 配置
# 只要在/etc/supervisord.d/目錄下所有 *.ini都會被管理
vi /etc/supervisord.d/redis.ini
[program:redis-server]
command=/usr/bin/redis-server /etc/redis/6379.conf
priority=999 ; 優先順序(越小越優先)
autostart=true ; supervisord啟動時,該程式也啟動
autorestart=true ; 異常退出時,自動啟動
startsecs=10 ; 啟動後持續10s後未發生異常,才表示啟動成功
startretries=3 ; 異常後,自動重啟次數
exitcodes=0,2 ; exit異常丟擲的是0、2時才認為是異常
stopsignal=QUIT ; 殺程序的訊號
; 在程式傳送stopignal後,等待作業系統將SIGCHLD返回給supervisord的秒數。
; 如果在supervisord從程序接收到SIGCHLD之前經過了這個秒數,
; supervisord將嘗試用最終的SIGKILL殺死它
stopwaitsecs=1
user=root ; 設定啟動該程式的使用者
log_stdout=true ; 如果為True,則記錄程式日誌
log_stderr=false ; 如果為True,則記錄程式錯誤日誌
logfile=/var/log/redis-server.log ; 程式日誌路徑
logfile_maxbytes=1MB ; 日誌檔案最大大小
logfile_backups=10 ; 日誌檔案最大數量
四 程序管理
# 1啟動supervisord管理的所有程序
supervisorctl start all
#2 停止supervisord管理的所有程序
supervisorctl stop all
#3 啟動supervisord管理的某一個特定程序
supervisorctl start program-name # program-name為[program:xx]中的xx
# 4 停止supervisord管理的某一個特定程序
supervisorctl stop program-name // program-name為[program:xx]中的xx
# 5 重啟所有程序或所有程序
supervisorctl restart all
# 重啟所有supervisorctl reatart program-name
# 重啟某一程序,program-name為[program:xx]中的xx
# 6 檢視supervisord當前管理的所有程序的狀態
supervisorctl status
五 使用 supervisorctl 客戶端命令
#Supervisorctl 是 supervisord 的一個命令列客戶端工具,啟動時需要指定與 supervisord 使用同一份配置檔案,否則與 supervisord 一樣按照順序查詢配置檔案
supervisorctl -c /etc/supervisord.conf
# 上面這個命令會進入 supervisorctl 的 shell 介面,然後可以執行不同的命令了:
supervisorctl # 或者啟動後,直接使用 (進入shell介面)
> status # 檢視程式狀態
> stop program-name # 關閉 program-name 程式
> start program-name # 啟動 program-name 程式
> restart program-name # 重啟 program-name 程式
> reread # 讀取有更新(增加)的配置檔案,不會啟動新新增的程式
> update # 重啟配置檔案修改過的程式
上面這些命令都有相應的輸出,除了進入 supervisorctl 的 shell 介面,等同於直接在 bash 終端執行:
$ supervisorctl status
$ supervisorctl stop usercenter
$ supervisorctl start usercenter
$ supervisorctl restart usercenter
$ supervisorctl reread
$ supervisorctl update
六 使用web管理
# 1 修改配置檔案
vim /etc/supervisord.conf
# 2 修改內容如下
[inet_http_server] ; inet (TCP) server disabled by default
port=0.0.0.0: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))
# 3 重啟
supervisorctl reload
# 4 在瀏覽器開啟:http://101.133.225.166:8080/
可以看到
七 Supervisor配置systemctl服務,開機自動啟
# 1 新建配置檔案
vim /usr/lib/systemd/system/supervisor.service
# 2 內容如下
[Unit]
Description=supervisor
After=network.target
[Service]
Type=forking
ExecStart=/usr/bin/supervisord -c /usr/local/supervisord.conf
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
# 3 幹掉原先的supervisor程序
ps -ef|grep super
root 14465 1 0 00:58 ? 00:00:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf
kill 14465
#4 使用systemctl啟動
systemctl start supervisor.service
systemctl status supervisor.service
#5 開機自啟
systemctl enable supervisor.service
八 Supervisor管理redis和nginx
8.1 配置nginx
#1 vim /etc/vim /etc/supervisord.d/nginx.ini
# 2 寫入
[program:nginx]
command=/usr/sbin/nginx -g 'daemon off;'
autostart=true ; 自動啟動
autorestart=true ; 自動重啟
user=root ; 以哪個使用者執行
stdout_logfile=/tmp/supervisor_nginx.log ; 日誌路徑
8.2 配置redis
#1 vim /etc/vim /etc/supervisord.d/redis.ini
# 2 寫入
[program:redis]
command=redis-server
autostart=true ; 自動啟動
autorestart=true ; 自動重啟
user=root ; 以哪個使用者執行
stdout_logfile=/tmp/supervisor_redis.log ; 日誌路徑
8.3 重啟
supervisorctl shutdown
supervisord -c /etc/supervisord.conf
# 或者
supervisorctl reload
8.4 測試
# 殺死nginx程序
# 殺死redis程序
redis-cli
輸入:shutwodn
# 發現服務又自動重啟了
九 常見問題及解決
9.1 問題一
# 報錯
BACKOFF Exited too quickly (process log may have details)
# 原因
supervisor 比較適合監控業務應用,且只能監控前臺程式,實現的daemon【後臺啟動】的程式不能用它監控,否則supervisor> status 會提示:BACKOFF Exited too quickly (process log may have details)
9.2 問題二
# 報錯
FATAL Exited too quickly (process log may have details
# 原因
錯誤FATAL產生的原因可能是你的python命令的環境配置有問題,如果你是虛擬環境配置的話,必須使用虛擬環境的路徑的python或gunicorn命令否則會失敗!
# 解決
[program:gunicorn]
command=/root/.local/share/virtualenvs/blog/bin/gunicorn -c other_config/gunicorn.py main:app
#; 這裡的gunicorn必須是你執行python環境對應的環境【如果是虛擬環境就必須配置虛擬環境的路徑下面的命令】
autostart = true ; 在 supervisord 啟動的時候也自動啟動
9.3 問題三
# 報錯
啟動了多個supervisord服務,導致無法正常關閉服務
在執行supervisord -c /etc/supervisord.conf之前,直接執行過supervisord -c /etc/supervisord.d/xx.conf導致有些程序被多個superviord管理,無法正常關閉程序。
# 解決
使用ps -fe | grep supervisord檢視所有啟動過的supervisord服務,kill相關的程序。
9.4 問題四
# 報錯
unix:///var/run/supervisor/supervisor.sock no such file
# 解決
sudo chmod 777 /run
sudo chmod 777 /var/log
9.5 問題五
# 報錯
Unlinking stale socket /var/run/supervisor/supervisor.sock
# 解決(或者直接刪除)
unlink /var/run/supervisor/supervisor.sock
9.6 問題六
#報錯
Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting supervisord.
# 解決
ps aux | grep supervisord
kill - 9 程序ID