Supervisor详解:Linux进程管理的终极利器

Supervisor 是什么

Supervisor 是 Python 开发的进程管理工具:把普通命令行进程变成后台守护进程,监控运行状态,异常退出自动重启,并提供统一的管理界面。核心特性:

  • 简单易用:INI 风格配置文件,支持自动重启与日志轮转;
  • 集中管理:命令行(supervisorctl)和 Web 界面统一管理多个进程;
  • 稳定:用 fork/exec 启动子进程,子进程退出时操作系统立即通知 supervisord;
  • 可扩展:事件通知协议 + XML-RPC 接口,可自定义监控报警。

核心组件

  • supervisord:服务端主进程,负责启停子进程、响应客户端、记录日志;
  • supervisorctl:命令行客户端;
  • Web 界面:配置 inet_http_server 后浏览器访问;
  • XML-RPC:给 Web UI 和第三方程序用的编程接口。

安装

# Debian/Ubuntu
sudo apt-get install supervisor

# CentOS/RHEL
sudo yum install supervisor    # 或 dnf

# pip 方式
pip install supervisor

安装后关键文件:主配置 /etc/supervisord.conf、子配置目录 /etc/supervisord.d/、命令 supervisord / supervisorctl

配置详解

主配置(supervisord.conf)

[unix_http_server]
file=/tmp/supervisor.sock
chmod=0700

[inet_http_server]          ; Web 管理界面(注意鉴权与访问范围)
port=127.0.0.1:9001
username=user
password=123

[supervisord]
logfile=/tmp/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=/tmp/supervisord.pid
nodaemon=false              ; true 时前台运行(Docker 里用)

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock

[include]
files = supervisord.d/*.conf

程序配置(/etc/supervisord.d/myapp.conf)

[program:myapp]
command=/path/to/program --flag    ; 要执行的命令(绝对路径)
directory=/path/to/workdir         ; 工作目录
user=myuser                        ; 运行用户
autostart=true                     ; supervisord 启动时自动拉起
autorestart=true                   ; 异常退出自动重启
startsecs=10                       ; 启动后稳定运行 10 秒才算启动成功
startretries=3                     ; 启动失败重试次数
stdout_logfile=/var/log/myapp.out.log
stderr_logfile=/var/log/myapp.err.log
environment=KEY="value"            ; 环境变量

关键参数语义:startsecs 防止”刚启动就崩”被误判为稳定;autorestart 是”挂了自动拉起”的开关——排查”不自动重启”先看它。

常用命令

supervisord -c /etc/supervisord.conf   # 启动服务
supervisorctl reread                   # 重新读取配置
supervisorctl update                   # 应用配置变更(改配置后必须执行)
supervisorctl start|stop|restart myapp
supervisorctl status
supervisorctl start all                # 操作全部

高级功能

进程组

[group:apps]
programs=app1,app2,app3
# 组内操作:supervisorctl start apps:*

日志轮转

[program:myapp]
stdout_logfile=/var/log/myapp.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=10

事件监听(异常报警)

[eventlistener:crash_alert]
command=python3 alert.py
events=PROCESS_STATE_EXITED
# alert.py:按事件协议读写 stdin/stdout
import sys, requests

while True:
    headers = sys.stdin.readline()
    payload = sys.stdin.readline()
    sys.stdout.write("READYn")
    sys.stdout.flush()
    if "PROCESS_STATE_EXITED" in payload:
        requests.post("https://your-webhook", json={"text": "程序挂了!"})

事件监听协议要求:读完两行(headers + payload)后回写 READY 并 flush——这是新手最容易卡住的地方。

Docker 容器内管理多服务

# 容器内 supervisord 必须前台运行
[supervisord]
nodaemon=true

[program:nginx]
command=nginx -g 'daemon off;'     # 前台模式
autostart=true
autorestart=true

常见问题

  • 不自动重启:检查 autorestart(true 或 unexpected);
  • 改配置不生效:必须 supervisorctl reread && update
  • 日志不生成:目录写权限问题;
  • Web 打不开:inet_http_server 配置 + 防火墙/安全组;
  • 进程起不来:command 用绝对路径、确认运行用户有执行权限;先手动跑一遍命令验证。
滚动至顶部