简介说明
Supervisor 是一个用 Python 开发的进程管理工具,可以很方便地监听、启动、停止、重启一个或多个进程。当一个进程意外被杀死,Supervisor 监听到进程死后,会自动将它重新拉起,很方便的做到进程自动恢复的功能,不再需要自己写 shell 脚本来控制。
主要特点
进程监控:实时监控进程状态,自动重启异常退出的进程
统一管理:通过配置文件统一管理多个进程,支持分组管理
日志管理:自动处理进程的标准输出和错误输出,支持日志轮转
Web 界面:提供 Web 管理界面,方便远程管理(可选)
命令行工具:提供 supervisorctl 命令行工具,支持启动、停止、重启等操作
开机自启:支持系统启动时自动启动被管理的进程
用户权限:支持以不同用户身份运行不同的进程
适用场景
Web 应用服务(如 Django、Flask、FastAPI 等)
后台任务和定时任务
数据处理脚本
微服务架构中的各个服务
需要长期运行的 Python 脚本或其他程序
安装卸载
Ubuntu 系统
# 安装
sudo apt-get install supervisor
# 验证安装,不报错则说明安装启动成功
sudo supervisorctl status
# 卸载
# (Step 01)停止 supervisor 服务
sudo systemctl stop supervisor
# (Step 02)禁用开机自启动
sudo systemctl disable supervisor
# (Step 03)卸载 supervisor 软件包
sudo apt-get purge supervisor
sudo apt-get autoremove
# (Step 04)手动删除残留的配置文件和日志
sudo rm -rf /etc/supervisor
sudo rm -rf /var/log/supervisor
sudo rm -f /var/run/supervisord.pid
sudo rm -f /var/run/supervisor/supervisor.sock
# (Step 05)验证卸载是否成功
sudo supervisorctl status
# 应该提示命令未找到
配置文件
主配置文件
# Ubuntu 系统
# 初始主配置文件: /etc/supervisor/supervisord.conf
# 注释符号为 ;
# 该初始配置文件已足够满足基础功能,因此无需修改、保持默认,即可正常使用
# 如有特殊需求,可按需更改
[unix_http_server]
file=/var/run/supervisor/supervisor.sock ; Unix Socket 文件路径,supervisorctl 客户端通过此文件与 supervisord 通信,如果文件不存在会自动创建,确保目录存在且有正确权限
;chmod=0700 ; Socket 文件的权限模式,默认为 0700(仅所有者可读写执行)
;chown=nobody:nogroup ; Socket 文件的所有者,格式为 用户名:组名,默认为当前用户
;username=user ; 连接 Unix Socket 时的用户名验证,默认无需用户名
;password=123 ; 连接 Unix Socket 时的密码验证,默认无需密码
;[inet_http_server] ; HTTP 服务器配置段,启用后可通过 Web 界面管理 supervisor
;port=127.0.0.1:9001 ; Web 管理界面的 IP 地址和端口,建议仅绑定本地地址以确保安全
;username=user ; Web 管理界面的登录用户名
;password=123 ; Web 管理界面的登录密码,生产环境请使用强密码
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; supervisord 主进程日志文件路径,记录 supervisor 自身的运行日志
logfile_maxbytes=50MB ; 日志文件的最大大小,超过此大小会自动轮转,设为 0 表示不限制大小
logfile_backups=10 ; 日志文件轮转时保留的备份文件数量,设为 0 表示不保留备份
loglevel=info ; 日志记录级别,可选值:critical, error, warn, info, debug, trace
pidfile=/var/run/supervisord.pid ; supervisord 主进程的 PID 文件路径,用于进程管理
nodaemon=false ; 是否以前台模式运行,false 表示以守护进程(后台)模式运行
minfds=1024 ; supervisord 启动时可用的最小文件描述符数量,系统资源限制
minprocs=200 ; supervisord 启动时可用的最小进程数量,系统资源限制
;umask=022 ; 创建文件时的默认权限掩码,022 表示创建的文件对组和其他用户只读
;user=chrism ; 运行 supervisord 的用户身份,默认为当前用户,以 root 启动时必须指定
;identifier=supervisor ; supervisord 实例的标识符,用于区分多个 supervisor 实例
;directory=/tmp ; supervisord 启动时的工作目录,默认不切换目录
;nocleanup=true ; 启动时是否清理临时文件,false 表示清理,true 表示不清理
;childlogdir=/tmp ; 子进程日志文件的默认目录,AUTO 表示使用系统临时目录
;environment=KEY=value ; 传递给所有子进程的环境变量,格式为 KEY1=value1,KEY2=value2
;strip_ansi=false ; 是否从日志中移除 ANSI 转义序列(颜色代码),默认保留
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
; RPC 接口配置,用于 supervisorctl 与 supervisord 之间的通信,通常无需修改
[supervisorctl]
serverurl=unix:///var/run/supervisor/supervisor.sock ; supervisorctl 连接 supervisord 的方式,使用 Unix Socket
;serverurl=http://127.0.0.1:9001 ; 也可以通过 HTTP 方式连接,需要启用 inet_http_server
;username=chris ; 连接时使用的用户名,应与服务器端配置一致
;password=123 ; 连接时使用的密码,应与服务器端配置一致
;prompt=mysupervisor ; supervisorctl 交互模式下的命令提示符,默认为 "supervisor"
;history_file=~/.sc_history ; 命令历史记录文件路径,支持 readline 库时有效
; [program:xx] 是被管理的进程配置段,xx 是进程的名称,每个进程需要单独配置
;[program:theprogramname]
;command=/bin/cat ; 程序启动命令,完整的可执行文件路径和参数
;process_name=%(program_name)s ; 进程名称表达式,默认使用 program 名称,支持变量替换
;numprocs=1 ; 启动的进程副本数量,默认为 1,可以启动多个相同进程
;directory=/tmp ; 程序执行前切换到的工作目录,默认不切换目录
;umask=022 ; 进程创建文件时的权限掩码,默认为 None(继承父进程)
;priority=999 ; 进程启动优先级,数值越小优先级越高,默认为 999
;autostart=true ; supervisord 启动时是否自动启动此进程,默认为 true
;autorestart=true ; 进程异常退出后是否自动重启,可选值:false(不重启)、unexpected(仅意外退出时重启)、true(总是重启)
;startsecs=10 ; 进程启动后持续运行多少秒才认为启动成功,默认为 1 秒
;startretries=3 ; 进程启动失败时的最大重试次数,默认为 3 次
;exitcodes=0,2 ; 进程正常退出的返回码列表,默认为 0,2,其他返回码视为异常退出
;stopsignal=QUIT ; 停止进程时发送的信号,默认为 TERM,可选:TERM、HUP、INT、QUIT、KILL、USR1、USR2
;stopwaitsecs=10 ; 发送停止信号后等待进程退出的最大秒数,超时后发送 SIGKILL 强制终止
;user=chrism ; 运行进程的用户身份,默认为 root 或当前用户
;redirect_stderr=true ; 是否将标准错误重定向到标准输出,默认为 false
;stdout_logfile=/a/path ; 标准输出日志文件路径,需确保目录存在,supervisord 会自动创建日志文件
;stdout_logfile_maxbytes=1MB ; 标准输出日志文件的最大大小,默认为 50MB,超过后自动轮转
;stdout_logfile_backups=10 ; 标准输出日志文件轮转时保留的备份数量,默认为 10 个
;stdout_capture_maxbytes=1MB ; 捕获模式下标准输出的最大字节数,默认为 0(不限制)
;stdout_events_enabled=false ; 是否在标准输出写入时发出事件,默认为 false
;stderr_logfile=/a/path ; 标准错误日志文件路径,NONE 表示不记录,AUTO 表示自动处理
;stderr_logfile_maxbytes=1MB ; 标准错误日志文件的最大大小,默认为 50MB
;stderr_logfile_backups=10 ; 标准错误日志文件轮转时保留的备份数量,默认为 10 个
;stderr_capture_maxbytes=1MB ; 捕获模式下标准错误的最大字节数,默认为 0(不限制)
;stderr_events_enabled=false ; 是否在标准错误写入时发出事件,默认为 false
;environment=A=1,B=2 ; 传递给进程的环境变量,格式为 KEY1=value1,KEY2=value2
;serverurl=AUTO ; 子进程工具的服务器 URL 计算方式,通常使用 AUTO 自动计算
; [include] 配置段用于包含其他配置文件,实现配置文件的模块化管理
[include]
; 指定一个或多个 .conf 子配置文件
files = conf.d/*.conf
; 此处是相对路径,绝对路径为 /etc/supervisor/conf.d/*.conf
; 多个文件用空格分隔,如:/etc/supervisor/conf.d/*.conf /opt/app/*.conf
; 建议将不同项目的 .conf 配置文件放在 /etc/supervisor/conf.d/ 目录下
; 每个项目创建独立的 .conf 子配置文件,便于管理和维护
子配置文件
# Ubuntu 系统
# 子配置文件: /etc/supervisor/conf.d/*.conf
# 在 /etc/supervisor/conf.d/ 文件夹内的任意 .conf 文件均为一个个待监管的子配置文件
# 建议每个项目创建独立的 .conf 子配置文件,便于管理和维护
# 子配置文件需要有正确的权限:sudo chmod 644 /etc/supervisor/conf.d/*.conf
# 注释符号为 ;
# 新建子配置文件
# /etc/supervisor/conf.d/my_server.conf 配置文件内容及解析示例如下:
; program: 定义子服务名称,便于管理
[program:myitem]
; directory: 项目代码目录文件夹(推荐使用绝对路径)
; 如待运行的代码文件为 /home/faramita/PythonWorks/my_item/my_app.py
; 则 directory=/home/faramita/PythonWorks/my_item
directory=/home/faramita/PythonWorks/my_item
; command: 执行命令,总的来说就是 执行器路径 + 待执行文件路径(以 directory 为当前所在目录) + 其他参数,如:
; (1)Python 项目:
; command=/home/faramita/anaconda3/envs/my_item_py310/bin/python test.py
; (2)Gunicorn 托管的 Python 项目:
; command=/home/faramita/anaconda3/envs/my_item_py310/bin/gunicorn App_Http_Server:app --workers 1 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:12321 --timeout 300
; (3).sh 脚本:
; command=/bin/bash test.sh --id=3
; (4)二进制可执行文件:
; command=/home/faramita/chfs --file="/home/faramita/chfs.ini"
; (5)按顺序执行多个命令:
; command=/bin/bash -c "cd /app && /opt/conda/envs/voice-clone/bin/python AppInit.py && /opt/conda/envs/voice-clone/bin/python AppHttpServer.py"
command=/home/faramita/anaconda3/envs/my_item_py310/bin/gunicorn App_Http_Server:app --workers 1 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:12321 --timeout 300
; 停止进程时发送的信号,默认为 TERM,可选值:TERM、HUP、INT、QUIT、KILL、USR1、USR2
stopsignal=TERM
; 发送停止信号后等待进程正常退出的最大秒数,超时后会发送 SIGKILL 强制终止进程,默认为 10 秒
stopwaitsecs=60
; supervisor 启动的时候是否随着同时启动,默认 True
autostart=true
; 设置子进程挂掉后自动重启的情况,有三个选项[false, unexpected, true],为 false 时,无论什么情况下都不会被重新启动
autorestart=true
; 子进程启动多少秒之后,此时状态如果是 running,则认为启动成功,默认值为 1
startsecs=30
; 脚本代码运行的身份
user=root
; 把 stderr 重定向到 stdout,默认 false
redirect_stderr=true
; 日志输出
stdout_logfile=/home/faramita/PythonWorks/my_item/run.log
; stdout 日志文件大小,默认 50MB
stdout_logfile_maxbytes=20MB
; stdout日志文件备份数
stdout_logfile_backups=50
; 错误日志输出
stderr_logfile=/home/faramita/PythonWorks/my_item/run_error.log
; stderr 日志文件大小,默认 50MB
stderr_logfile_maxbytes=20MB
; stderr 日志文件备份数
stderr_logfile_backups=50
; 环境变量,等价于在终端中直接设置:export xxx,其他环境变量用 逗号 分隔
; 如:使用 GPU 多卡
; environment=CUDA_VISIBLE_DEVICES="0,1"
; 如:使用 GPU 全部可用卡号,设为空字符串,或不设置此环境变量
; environment=CUDA_VISIBLE_DEVICES=""
environment=CUDA_VISIBLE_DEVICES="0",OTHER_ENV_VAR="value"
# 若一个项目内有多个服务需要 supervisor 监管,则在该项目的 .conf 子配置文件中定义多个子服务名称即可
# /etc/supervisor/conf.d/my_server.conf 配置文件内容及解析示例如下:
[program:myitem_1]
directory=xxx
command=xxx
...
[program:myitem_2]
directory=xxx
command=xxx
...
管理控制
Ubuntu 系统
管理 supervisor
# 查看 supervisor 安装目录
whereis supervisord
# 开机自启动
sudo systemctl enable supervisor
# 启动 supervisor 服务
sudo systemctl start supervisor
# 停止 supervisor 服务
sudo systemctl stop supervisor
# 重启 supervisor 服务
sudo systemctl restart supervisor
# 查看 supervisor 服务状态
sudo systemctl status supervisor
# 查看 supervisor 服务日志
sudo journalctl -u supervisor -f
监管服务
# 更新配置(如果修改了配置文件要重新读取并更新)
sudo supervisorctl reread && sudo supervisorctl update
# 查看所有应用状态
sudo supervisorctl status
# 重启所有应用
sudo supervisorctl reload
# 开启/关闭 指定应用
sudo supervisorctl start <应用名称>
sudo supervisorctl stop <应用名称>
sudo supervisorctl restart <应用名称>
# 查看应用日志(实时)
sudo supervisorctl tail -f <应用名称>
# 清除应用日志
sudo supervisorctl clear <应用名称>
# 移除应用
sudo supervisorctl remove <应用名称>
# 进入 supervisorctl 交互模式
sudo supervisorctl
评论区