Supervisor 教程(2026):安装配置、常见问题与 Supervisor vs systemd 选型
面向 Linux 运维与开发者的 Supervisor 实战指南:安装配置、进程托管、常见故障排查,以及与 systemd/PM2 的选型对比。
1442 Words
2018-10-07 00:35 +0000
Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便地启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,比如服务器异常后快速拉起整组服务。
先说结论(给赶时间的你):
- 你在维护多个业务进程(队列 worker、定时任务、爬虫、脚本服务)时,Supervisor 依然非常好用。
- 如果你追求系统原生管理、与 Linux 服务深度集成,优先考虑 systemd。
- Node.js 生态下,如果只托管单个应用,PM2 也可选,但跨语言统一托管时 Supervisor 更顺手。
Supervisor vs systemd vs PM2(先选型)
| 维度 | Supervisor | systemd | PM2 |
|---|---|---|---|
| 适用场景 | 多进程统一托管(跨语言) | Linux 系统级服务管理 | Node.js 应用管理 |
| 学习成本 | 中等 | 偏高 | 低 |
| 开机自启 | 支持 | 强(原生) | 支持 |
| 日志管理 | 基础可用 | 强 | 友好 |
| 推荐人群 | 运维/后端/多脚本场景 | 强 Linux 运维团队 | Node 开发者 |
实战建议:已有 systemd 体系的生产环境,优先 systemd;需要快速统一托管多类进程时,Supervisor 依然是高性价比方案。
安装
服务器上所有应用统一安装到目录/usr/local/programs/,所以采用源码安装
提前配置好python(2.7)环境,下载相关文件:
wget wget https://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg –no-check-certificate
按下面步骤执行:
1. sh setuptools-0.6c11-py2.7.egg
2. tar -axvf supervisor-3.3.1.tar.gz
3. cd supervisor-3.3.1
4. python setup.py install
5. echo_supervisord_conf > /usr/local/programs/supervisoretc/supervisord.conf
6. supervisord -c /usr/local/programs/supervisoretc/supervisord.conf
7. supervisorctl
8. done
配置文件supervisord.conf:
; Sample supervisor config file.
;
; For more information on the config file, please see:
; http://supervisord.org/configuration.html
;
; Notes:
; - Shell expansion ("~" or "$HOME") is not supported. Environment
; variables can be expanded using this syntax: "%(ENV_HOME)s".
; - Comments must have a leading space: "a=b ;comment" not "a=b;comment".
[unix_http_server]
file=/tmp/supervisor.sock ; (the path to the socket file)
;chmod=0700 ; socket file mode (default 0700)
;chown=nobody:nogroup ; socket file uid:gid owner
;username=user ; (default is no username (open server))
;password=123 ; (default is no password (open server))
[inet_http_server] ; inet (TCP) server disabled by default
port=0.0.0.0:9001 ; (ip_address:port specifier, *:port for all iface)
;username=user ; (default is no username (open server))
;password=123 ; (default is no password (open server))
[supervisord]
logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
;umask=022 ; (process file creation umask;default 022)
;user=chrism ; (default is current user, required if root)
;identifier=supervisor ; (supervisord identifier, default is 'supervisor')
;directory=/tmp ; (default is not to cd during start)
;nocleanup=true ; (don't clean up tempfiles at start;default false)
;childlogdir=/tmp ; ('AUTO' child log dir, default $TEMP)
;environment=KEY="value" ; (key value pairs to add to environment)
;strip_ansi=false ; (strip ansi escape codes in logs; def. false)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris ; should be same as http_username if set
;password=123 ; should be same as http_password if set
;prompt=mysupervisor ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history ; use readline history if available
; The below sample program section shows all possible program subsection values,
; create one or more 'real' program: sections to be able to control them under
; supervisor.
;[program:theprogramname]
;command=/bin/cat ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1 ; number of processes copies to start (def 1)
;directory=/tmp ; directory to cwd to before exec (def no cwd)
;umask=022 ; umask for process (default None)
;priority=999 ; the relative start priority (default 999)
;autostart=true ; start at supervisord start (default: true)
;startsecs=1 ; # of secs prog must stay up to be running (def. 1)
;startretries=3 ; max # of serial start failures when starting (default 3)
;autorestart=unexpected ; when to restart if exited after running (def: unexpected)
;exitcodes=0,2 ; 'expected' exit codes used with autorestart (default 0,2)
;stopsignal=QUIT ; signal used to kill process (default TERM)
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false ; send stop signal to the UNIX process group (default false)
;killasgroup=false ; SIGKILL the UNIX process group (def false)
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=true ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A="1",B="2" ; process environment additions (def no adds)
;serverurl=AUTO ; override serverurl computation (childutils)
; The below sample eventlistener section shows all possible
; eventlistener subsection values, create one or more 'real'
; eventlistener: sections to be able to handle event notifications
; sent by supervisor.
;[eventlistener:theeventlistenername]
;command=/bin/eventlistener ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1 ; number of processes copies to start (def 1)
;events=EVENT ; event notif. types to subscribe to (req'd)
;buffer_size=10 ; event buffer queue size (default 10)
;directory=/tmp ; directory to cwd to before exec (def no cwd)
;umask=022 ; umask for process (default None)
;priority=-1 ; the relative start priority (default -1)
;autostart=true ; start at supervisord start (default: true)
;startsecs=1 ; # of secs prog must stay up to be running (def. 1)
;startretries=3 ; max # of serial start failures when starting (default 3)
;autorestart=unexpected ; autorestart if exited after running (def: unexpected)
;exitcodes=0,2 ; 'expected' exit codes used with autorestart (default 0,2)
;stopsignal=QUIT ; signal used to kill process (default TERM)
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false ; send stop signal to the UNIX process group (default false)
;killasgroup=false ; SIGKILL the UNIX process group (def false)
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=false ; redirect_stderr=true is not allowed for eventlisteners
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A="1",B="2" ; process environment additions
;serverurl=AUTO ; override serverurl computation (childutils)
; The below sample group section shows all possible group values,
; create one or more 'real' group: sections to create "heterogeneous"
; process groups.
;[group:thegroupname]
;programs=progname1,progname2 ; each refers to 'x' in [program:x] definitions
;priority=999 ; the relative start priority (default 999)
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = conf.d/*.conf
注意最下面一行,重点,要考!
配置管理程序
以nginx为例,在/usr/local/programs/supervisor/conf.d下创建
vi nginx.conf
[program:nginx]
command=/usr/local/programs/nginx/nginx ;需要执行的命令wd
user=root ;(default is current user , required if root)
autostart=true ;start at supervisord start (default: true)
autorestart=true ;whether/when to restart (default: unexpected)
startsecs=3 ;number of secs prog must stay running ( def . 1)
stderr_logfile=/usr/local/programs/supervisor/logs/nginx_stderr_err.log ;redirect proc stderr to stdout (default false) 错误输出重定向
stdout_logfile=/usr/local/programs/supervisor/logs/nginx_stdout.log ;stdout log path, NONE for none; default AUTO, log输出
wq保存退出,启动 supervisord -c /etc/supervisord.conf
Supervisorctl工具
进入交互模式supervisorctl
> status # 查看程序状态
> stop usercenter # 关闭 usercenter 程序
> start usercenter # 启动 usercenter 程序
> restart usercenter # 重启 usercenter 程序
> reread # 读取有更新(增加)的配置文件,不会启动新添加的程序
> update # 重启配置文件修改过的程序
也可以不进入交互环境
$ supervisorctl status
$ supervisorctl stop usercenter
$ supervisorctl start usercenter
$ supervisorctl restart usercenter
$ supervisorctl reread
$ supervisorctl update
开机启动
ubuntu
打开配置vi /etc/rc.local
增加自启动配置项目
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
#开机自启动
/bin/bash -c "/usr/local/bin/supervisord -c /usr/local/programs/supervisor/supervisord.conf"
exit 0
保存并退出。
最后修改rc.local权限 chmod +x /etc/rc.local
更新说明(2026):在较新的 Ubuntu/Debian 上,
rc.local方案已不推荐,建议使用 systemd 托管supervisord服务。
推荐的 systemd 启动方式(替代 rc.local)
创建服务文件:/etc/systemd/system/supervisord.service
[Unit]
Description=Supervisor daemon
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/supervisord -c /usr/local/programs/supervisor/supervisord.conf
ExecStop=/usr/local/bin/supervisorctl shutdown
ExecReload=/usr/local/bin/supervisorctl reload
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
执行:
sudo systemctl daemon-reload
sudo systemctl enable supervisord
sudo systemctl start supervisord
sudo systemctl status supervisord
常见故障排查(实战高频)
1) unix:///tmp/supervisor.sock no such file
- 原因:
supervisord没启动或 socket 路径不一致。 - 处理:先
supervisord -c ...,再确认supervisord.conf与supervisorctl的serverurl配置一致。
2) 程序一直 BACKOFF / FATAL
- 原因:
command写错、依赖没装、启动即退出。 - 处理:检查
stdout_logfile/stderr_logfile,手动执行一次 command 验证可运行。
3) autorestart 不生效
- 原因:
exitcodes与进程实际退出码不匹配,或startsecs太短。 - 处理:设置
autorestart=unexpected,并调整startsecs、startretries。
4) permission denied
- 原因:运行用户无执行或目录权限。
- 处理:确认
user=、日志目录可写、可执行文件权限正确。