Linux · 运维 · Supervisor

用 Supervisor 守护你的后台进程

从安装、配置到日常运维,快速掌握如何用 Supervisor 管理 Python、Node.js 等长期运行的服务。

手动在终端里启动一个 Web 服务很直接:运行命令,看到日志,服务就起来了。但 SSH 连接断开、进程异常退出或机器重启后,服务往往也随之消失。对于还没有接入 systemd、容器编排平台的小型服务,Supervisor 是一个简单可靠的进程守护工具。

它负责启动指定命令、观察进程状态、在需要时重启进程,并把标准输出和错误输出写入日志。它并不替代 Nginx、数据库或发布系统;更适合用来管理常驻的应用进程、队列消费者和定时任务。

安装与启动

Supervisor 通常通过 Python 包管理器安装。建议在系统 Python 或专门的运维虚拟环境中安装,避免依赖某个应用自己的虚拟环境:

python3 -m pip install supervisor

安装后先生成一份默认配置,再按发行版习惯将它放到 /etc/supervisord.conf 或其他统一的位置:

echo_supervisord_conf > supervisord.conf
supervisord -c supervisord.conf
supervisorctl -c supervisord.conf status

许多 Linux 发行版也提供系统包。通过系统包装好后,服务名、默认配置路径和开机启动方式可能不同;先查看该发行版的包说明或 systemd 单元文件,不要混用两套配置。

配置一个程序

实际项目中,通常保留主配置文件,只把每个程序写成独立的 conf.d/*.conf 文件,再通过 [include] 统一加载:

; /etc/supervisor/conf.d/my-api.conf
[program:my-api]
directory=/srv/my-api
command=/srv/my-api/.venv/bin/gunicorn app:app --bind 127.0.0.1:8000
user=www-data

autostart=true
autorestart=unexpected
startsecs=5
startretries=3

stdout_logfile=/var/log/supervisor/my-api.log
stderr_logfile=/var/log/supervisor/my-api-error.log
environment=APP_ENV="production",PORT="8000"

主配置中加入下面的片段即可加载该目录:

[include]
files = /etc/supervisor/conf.d/*.conf

几个字段尤其重要:

对于 Node.js 服务,同样的思路适用,只需把 command 改为 Node 的绝对路径和启动脚本,例如 /usr/bin/node /srv/my-app/dist/server.js

让配置生效

修改或新增配置后,按下面的顺序操作:

supervisorctl reread
supervisorctl update
supervisorctl status

reread 只重新扫描配置,并不启动或停止任何进程;update 才会根据差异添加新程序、移除已删除的程序,并重启发生配置变化的程序。把两者分开执行,有助于在生产环境确认变更范围。

日常控制命令也很直观:

supervisorctl status
supervisorctl start my-api
supervisorctl restart my-api
supervisorctl stop my-api
supervisorctl tail -f my-api stderr

如果配置了组,还可以使用 group:* 一次操作整个组。例如将多个消费者放进 [group:workers],再运行 supervisorctl restart workers:*

日志、退出码与重启策略

Supervisor 能重启进程,但不能判断业务是否健康。因此要把“进程还活着”和“服务可用”分开对待:前者由 Supervisor 负责,后者仍需要健康检查、监控与告警。

默认情况下,程序以退出码 0 退出会被视为预期退出。一个原本应长期运行的服务若因配置错误很快退出,startsecs 会让 Supervisor 将其认定为启动失败;超过 startretries 后,程序状态会变成 FATAL,避免无限快速重启。

常见日志排查顺序如下:

  1. 运行 supervisorctl status,确认程序是 RUNNINGBACKOFF 还是 FATAL
  2. 查看应用的 stderr_logfile,优先寻找启动命令、权限、端口占用和依赖缺失等错误。
  3. 查看 supervisord 自身日志,确认配置是否被加载、用户是否有权限创建日志文件。
  4. 在与配置相同的 userdirectory 和环境变量下手动执行 command,缩小 Supervisor 与应用本身之间的问题边界。

日志文件会持续增长。生产环境应配合 logrotate,或使用集中式日志系统;不要仅依赖磁盘上的单个无限增长文件。

几个容易踩到的坑

何时选择其他方案

在现代 Linux 服务器上,如果服务本身由 systemd 管理,直接编写 systemd unit 往往更贴合系统的日志、权限和依赖管理。若应用已经运行在 Docker、Kubernetes 或其他编排平台里,也应优先使用对应平台的重启策略与健康检查。

Supervisor 的价值在于它的配置简单、控制接口统一,并且能快速把多个普通命令变成可观察、可重启的后台服务。先让启动命令能在命令行稳定运行,再交给 Supervisor 守护,通常会是最顺畅的开始。

参考资料