Python实现的进程管理神器——Supervisor的使用

.
.
.
参考博客 https://blog.csdn.net/lly1122334/article/details/122713267

简介


Supervisor 是一款Python 开发的进程管理系统,
允许用户监视和控制 Linux 上的进程,
能将一个普通命令行进程变为后台守护进程,异常退出时能自动重启

.
.
.
.

常用命令


# 修改配置并重启子进程
vim /etc/supervisor/conf.d/xxx.conf
supervisorctl reread
supervisorctl update
supervisorctl restart xxx
watch -n 1 "supervisorctl status"


# 查看进程状态   supervisorctl是客户端
supervisorctl status


# 查看 supervisord 的进程    supervisord是服务端
ps -ef | grep supervisord

.
.
.
.

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 操作

----------------------------------

.
.
.
.
.
.
.

安装及创建配置文件



Supervisor 支持 Linux 和 Mac,不支持 Windows
由于我安装了python,所以可以直接安装
pip3 install supervisor==4.2.4

--------------------------------------

# 以Ubuntu系统为例

1 调用命令  sudo echo_supervisord_conf > /etc/supervisord.conf
注意:可能echo_supervisord_conf不在你的环境变量目录下,可能要查找,
通常在python环境的bin目录下,如果不在可以去这个目录查找。

若报错 -bash: /etc/supervisord.conf: Permission denied,需要切换到 root
sudo su root

2 输出配置文件  cat /etc/supervisord.conf


# 3 创建子进程配置文件路径  mkdir -p /etc/supervisor/conf.d/

# 4 修改配置文件  sudo vim /etc/supervisord.conf

# 5 将最后一部分改为
[include]
files=/etc/supervisor/conf.d/*.conf


6 其余改成以下内容
[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 为例,创建启动脚本

使用 curl 工具从 GitHub 上的指定 URL 地址下载一个脚本文件,
并将其保存到 /etc/init.d/supervisord 文件中
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  # 查看服务状态

------------------------------------------

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
保存退出后,执行命令
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

访问 http://127.0.0.1:9001  就能看到supervisor客户端的状态了!!!

-----------------------------------------

.
.
.
.

配置文件


服务器进程使用的配置文件一般为 /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` 可改为 ``,放在与项目同一目录下


.
.
.
.

supervisorctl 命令


改动某配置文件,重载

supervisorctl update
1
新增某配置文件,重载

supervisorctl reread
1
重启 supervisord

supervisorctl reload
1
查看所有进程状态

supervisorctl status
1
查看指定进程状态

supervisorctl status <name>
1
启动所有子进程

supervisorctl start all
1
启动指定子进程

supervisorctl start <name>
1
重启所有子进程

supervisorctl restart all
1
重启指定子进程

supervisorctl restart <name>
1
停止所有子进程

supervisorctl stop all
1
停止指定子进程

supervisorctl stop <name>
1
添加子进程到进程组

supervisorctl add <name>
1
从进程组移除子进程,需要先stop。注意:移除后,需要使用reread和update才能重新运行该进程

supervisorctl reomve <name>


.
.
.
.
.
.
.
.


# 一般情况下,python项目可以用supervisor来启动

# 用supervisor来启动web网管服务器gunicorn或者uwsgi,让gunicorn或者uwsgi来多线程的启动多个后端项目

# 比如把gunicorn做成supervisor的子进程或者叫守护进程后
(就是搞一个子进程的配置文件,然后在supervisor自己的配置文件里面,申明一下子进程的配置文件在哪,例如
[include]
files=/etc/supervisor/conf.d/*.conf)

# 子进程的配置文件里面,把子进程执行的命令,执行命令所在的路径,尝试启动的最大次数等关键信息参数填好即可

.
.
.

posted @   tengyifan  阅读(46)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示