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