文章目录
- 常用命令
- 简介
- 安装
- 创建配置文件
- 开机自启
- 初试
- Web 界面
- 配置文件
- 子进程配置模板
- 可用变量
- supervisorctl 命令
- Supervisor 组件
- 卸载
- 遇到的坑
- 参考文献
常用命令
修改配置并重启子进程
vim /etc/supervisor/conf.d/xxx.conf
supervisorctl reread
supervisorctl update
supervisorctl restart xxx
watch -n 1 "supervisorctl status"
查看进程状态
supervisorctl status
查看 supervisord 的进程
ps -ef | grep supervisord
简介
Supervisor 是一款 Python 开发的进程管理系统,允许用户监视和控制 Linux 上的进程,能将一个普通命令行进程变为后台守护进程,异常退出时能自动重启
安装
Supervisor 支持 Linux 和 Mac,不支持 Windows
本文系统为 Ubuntu,supervisor==4.2.4
pip3 install supervisor
创建配置文件
sudo echo_supervisord_conf > /etc/supervisord.conf
若报错 -bash: /etc/supervisord.conf: Permission denied
,需要切换到 root
sudo su root
输出配置文件
cat /etc/supervisord.conf
创建子进程配置文件路径
mkdir -p /etc/supervisor/conf.d/
修改配置文件
sudo vim /etc/supervisord.conf
将最后一部分改为
[include]
files=/etc/supervisor/conf.d/*.conf
其余改成以下内容
[unix_http_server]
file=/var/run/supervisor.sock;
chmod=0777; 所有用户可操作
[supervisord]
logfile=/var/log/supervisord.log;
pidfile=/var/run/supervisord.pid;
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock;
开机自启
以 Ubuntu 为例
创建启动脚本
sudo curl https://raw.githubusercontent.com/Supervisor/initscripts/master/ubuntu > /etc/init.d/supervisord
添加执行权限
sudo chmod +x /etc/init.d/supervisord
查看 supervisord 的 pidfile 路径
which supervisord
which supervisorctl
cat /etc/supervisord.conf | grep logfile
cat /etc/supervisord.conf | grep pidfile
# pidfile=/var/run/supervisord.pid;
修改启动脚本的变量 DAEMON、SUPERVISORCTL、LOGDIR、PIDFILE、DAEMON_OPTS 与上一致
sudo vim /etc/init.d/supervisord
如
DAEMON=/usr/local/bin/supervisord
SUPERVISORCTL=/usr/local/bin/supervisorctl
LOGDIR=/var/log/supervisord.log
PIDFILE=/var/run/supervisord.pid
DAEMON_OPTS="-c /etc/supervisord.conf $DAEMON_OPTS"
配置
sudo update-rc.d supervisord defaults
sudo service supervisord stop
sudo service supervisord start
systemctl status supervisord.service # 查看服务状态
以 CentOS 为例
查看 supervisord 的位置,得到结果如 /usr/local/bin/supervisord
which supervisord
查看 supervisord 的位置,得到结果如 /usr/local/bin/supervisorctl
which supervisorctl
创建服务文件
sudo vim /usr/lib/systemd/system/supervisord.service
填入
[Unit]
Description=Supervisor daemon
[Service]
Type=forking
ExecStart=/usr/local/bin/supervisord
ExecStop=/usr/local/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/local/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
查看是否已启动 supervisord,若已启动,杀进程
ps -ef | grep supervisord
supervisorctl stop all
kill -9 xxx
配置
sudo systemctl daemon-reload # 重载系统管理配置
sudo systemctl enable supervisord # 开机自启动
sudo systemctl start supervisord # 启动服务
systemctl status supervisord # 查看服务状态
初试
启动 supervisord
supervisord
或
supervisord -c /etc/supervisord.conf
查看版本
supervisord -v
查看进程状态(还没配程序,此时空输出)
supervisorctl status
编写简单的 Shell 脚本
vim /tmp/echo_time.sh
内容如下
#!/bin/bash
while :
do
echo `date '+%Y-%m-%d %H:%m:%S'`
sleep 1
done
简单运行,Ctrl + C
sh /tmp/echo_time.sh
创建子进程配置文件
vim /etc/supervisor/conf.d/echo_time.conf
内容如下
[program:echo_time] ; 项目名
command=sh /tmp/echo_time.sh ; 脚本执行命令
autostart=true ; 在supervisor启动时自动启动,默认为true
autorestart=true ; 在意外退出时重新启动,默认为unexpected
startsecs=10 ; 子进程启动多少秒后状态为running则认为启动成功,默认为1
startretries=3 ; 尝试启动的最大次数,默认为3
exitcodes=0 ; 进程的预期退出代码列表,默认为0
stopsignal=QUIT ; 终止进程的信号,默认为TERM
stopwaitsecs=10 ; 在SIGKILL之前等待的最大秒数,默认为10
user=root ; 在某用户下设置uid来启动程序,默认不切换用户
redirect_stderr=true ; 是否合并stderr到stdout,默认为false
stdout_logfile=/tmp/echo_time.stdout.log ; stdout的输出文件,默认为AUTO
stdout_logfile_maxbytes=50MB ; stdout最大文件大小,默认为50MB
stdout_logfile_backups=10 ; stdout文件备份数,设为0则不备份,默认为10
重新读取配置并更新子进程
supervisorctl reread
supervisorctl update
再次查看进程状态
supervisorctl status
watch -n 1 "supervisorctl status"
动态输出运行情况
tail -f /tmp/echo_time.stdout.log
效果
Web 界面
修改配置文件
sudo vim /etc/supervisord.conf
取消注释
[inet_http_server]
port=*:9001 ; 此处改为*便于调试
重启 supervisord
supervisorctl reload
查看本机 IP
hostname -I
访问 http://127.0.0.1:9001(把 127.0.0.1 改成上述 IP)
配置文件
服务器进程使用的配置文件一般为 /etc/supervisord.conf
,格式为 Windows-INI
子进程配置文件在文件夹 /etc/supervisor/conf.d/
,可通过上述配置文件的最后一行指定
子进程配置模板
[program:echo_time] ; 项目名
command=/Envs/xxx/bin/gunicorn -w 4 -b 127.0.0.1:5000 -k gevent main:app ; 脚本执行命令
process_name=%(program_name)s ; 进程名,默认为%(program_name)s,同项目名
numprocs=1 ; 启动的程序实例数,默认为1
directory=/data/code/project ; 脚本执行路径
umask=022 ; 进程掩码,默认无
priority=999 ; 相对启动优先级,数值越小越优先,默认为999
autostart=true ; 在supervisor启动时自动启动,默认为true
autorestart=true ; 在意外退出时重新启动,默认为unexpected
startsecs=10 ; 子进程启动多少秒后状态为running则认为启动成功,默认为1
startretries=3 ; 尝试启动的最大次数,默认为3
exitcodes=0 ; 进程的预期退出代码列表,默认为0
stopsignal=QUIT ; 终止进程的信号,默认为TERM
stopwaitsecs=10 ; 在SIGKILL之前等待的最大秒数,默认为10
stopasgroup=false ; 是否把整个子进程的进程组停止,发送stop信号,默认为false
killasgroup=false ; 是否把整个子进程的进程组停止,发送kill信号,默认为false
user=root ; 在某用户下设置uid来启动程序,默认不切换用户
redirect_stderr=true ; 是否合并stderr到stdout,默认为false
stdout_logfile=/tmp/echo_time.stdout.log ; stdout的输出文件,默认为AUTO
stdout_logfile_maxbytes=50MB ; stdout最大文件大小,默认为50MB
stdout_logfile_backups=10 ; stdout文件备份数,设为0则不备份,默认为10
stdout_capture_maxbytes=1MB ; capture管道大小,默认为0,关闭管道
stdout_events_enabled=false ; 当进程写stdout时是否触发PROCESS_LOG_STDOUT事件,默认为false
stderr_logfile=/tmp/echo_time.stderr.log ; stderr的输出文件,默认为AUTO
stderr_logfile_maxbytes=50MB ; stderr最大文件大小,默认为50MB
stderr_logfile_backups=10 ; stderr文件备份数,设为0则不备份,默认为10
stderr_capture_maxbytes=1MB ; capture管道大小,默认为0,关闭管道
stderr_events_enabled=false ; 当进程写stderr时是否触发PROCESS_LOG_STDERR事件,默认为false
environment=A="1",B="2" ; 环境变量,默认无
serverurl=AUTO ; 进入supervisord的URL,默认为AUTO
简化版
[program:echo_time]
command=/Envs/xxx/bin/gunicorn -w 4 -b 127.0.0.1:5000 -k gevent main:app
directory=/data/code/project
autorestart=true
startsecs=10
stopsignal=QUIT
user=root
redirect_stderr=true
stdout_logfile=/var/log/%(program_name)s.log
environment=A="1",B="2"
stopasgroup=true
根据 Option to create directory of specified log files,不会自动创建日志目录,不存在的话会报错
TODO:`stdout_logfile` 可改为 ``,放在与项目同一目录下
可用变量
查看环境变量,含有的都可用
env
Supervisor 自带的变量
变量名 | 含义 |
group_name | |
here | 配置文件目录 |
host_node_name | |
numprocs | |
process_num | |
program_name | 程序名 |
supervisorctl 命令
改动某配置文件,重载
supervisorctl update
新增某配置文件,重载
supervisorctl reread
重启 supervisord
supervisorctl reload
查看所有进程状态
supervisorctl status
查看指定进程状态
supervisorctl status <name>
启动所有子进程
supervisorctl start all
启动指定子进程
supervisorctl start <name>
重启所有子进程
supervisorctl restart all
重启指定子进程
supervisorctl restart <name>
停止所有子进程
supervisorctl stop all
停止指定子进程
supervisorctl stop <name>
添加子进程到进程组
supervisorctl add <name>
从进程组移除子进程,需要先stop。注意:移除后,需要使用reread和update才能重新运行该进程
supervisorctl reomve <name>
Supervisor 组件
- supervisord
服务器部分称为 supervisord,负责启动子程序,响应客户端的命令,重新启动崩溃或退出的子进程,记录子进程的 stdout 和 stderr 输出等
服务器进程使用的配置文件一般为/etc/supervisord.conf
,格式为 Windows-INI
子进程配置文件在文件夹/etc/supervisor/conf.d/
- supervisorctl
客户端命令行部分称为 supervisorctl ,可以连接到不同的 supervisord 进程,获取子进程状态,停止和启动子进程,以及获取一个正在运行的进程列表 - Web Server
可以通过浏览器访问 Web 用户界面进行 supervisorctl 操作 - XML-RPC Interface
可以通过接口 API 进行 supervisorctl 操作
卸载
dpkg -l | grep supervisor
sudo apt-get autoremove supervisor
sudo apt-get --purge remove supervisor
pip3 uninstall supervisor
遇到的坑
1. 启动时报错 Unlinking stale socket /tmp/supervisor.sock
杀掉进程,删除该文件,重新启动
sudo unlink /tmp/supervisor.sock
ps -ef | grep supervisord
kill 9 xxx
2. 报错 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.
杀掉进程,删除该文件,重新启动
sudo unlink /tmp/supervisor.sock
ps -ef | grep supervisord
kill 9 xxx
3. 普通用户 supervisorctl status 报错 error: <class ‘PermissionError’>, [Errno 13] Permission denied: file: /usr/local/lib/python3.8/site-packages/supervisor/xmlrpc.py line: 560
chmod 777 /tmp/supervisor.sock
4. Ubuntu 用 pip 安装找不到文件
把 supervisord 复制到 /usr/bin/ 目录下
或指定目录安装
pip3 install supervisor --install-option="--install-scripts=/usr/local/bin"
或全局安装(建议这种)
sudo -H pip3 install supervisor
5. 报错 unix:///tmp/supervisor.sock no such file
vim /etc/supervisord.conf
改成以下内容
[unix_http_server]
file=/var/run/supervisor.sock;
[supervisord]
logfile=/var/log/supervisord.log;
pidfile=/var/run/supervisord.pid;
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock;
6. 报错 unknown error making dispatchers for ‘xxx’: EACCES
日志文件夹缺少写权限
chmod -R 777 /var/log/
参考文献
- Supervisor Documentation
- Supervisor GitHub
- Python supervisor 强大的进程管理工具
- Supervisor使用详解
- supervisor常用命令
- 服务器安装配置supervisor
- another program is already listening on a port that one of our HTTP servers is configured to use
- 4种方法来在Linux系统中查看IP地址
- Permession denied error when use supervisorctl
- supervisor(一)基础篇
- Supervisor - Can’t start supervisorctl as root or user (User is set in config)
- ubuntu server 16.04: cannot get supervisor to start automatically
- supervisor和Python多进程multiprocessing使用