想象一下这个场景:你花了三天三夜部署的Web服务,在凌晨3点突然崩溃了。传统解决方案可能是写个shell脚本定时检查进程状态,但你会发现这种方案存在三个致命缺陷:无法自动拉起进程、日志管理混乱、多进程协同困难。这就是supervisorctl的用武之地——它像是个24小时待命的运维管家,专门解决这类进程管理难题。
我最早接触supervisorctl是在管理爬虫集群时,当时有20多个爬虫进程需要保持常驻。传统方式下,每次服务器重启都要手动逐个启动,直到发现supervisorctl的autorestart功能后,工作效率直接提升了300%。这个工具特别适合需要长期运行的服务,比如:
与传统的init.d脚本对比,supervisorctl有三大不可替代的优势:
bash复制# 传统方式启动服务
sudo /etc/init.d/nginx start
# supervisorctl方式
supervisorctl start nginx_group
在Ubuntu 20.04上安装只需一条命令,但有几个隐藏坑点需要注意:
bash复制sudo apt-get install -y supervisor
systemctl enable supervisor # 关键!设置开机自启
安装完成后,建议立即修改默认配置:
bash复制sudo vim /etc/supervisor/supervisord.conf
找到这两项关键配置:
ini复制[unix_http_server]
file=/var/run/supervisor.sock # 确保socket文件路径正确
chmod=0700 # 权限设置避免连接失败
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock # 必须与上面路径一致
我推荐采用模块化配置方式,在/etc/supervisor/conf.d/目录下为每个服务创建独立文件。比如部署Flask应用时:
ini复制# /etc/supervisor/conf.d/flask_app.conf
[program:flask_app]
command=/home/user/venv/bin/gunicorn -w 4 app:app # 使用虚拟环境中的gunicorn
directory=/home/user/project # 指定工作目录
user=user
autostart=true
autorestart=true
stopsignal=QUIT
stopwaitsecs=30
stdout_logfile=/var/log/flask_app.out.log # 日志分离
stderr_logfile=/var/log/flask_app.err.log
environment=PYTHONPATH="/home/user/project" # 环境变量注入
遇到过最头疼的问题是权限配置不当导致启动失败,建议按照这个检查清单排查:
bash复制# 查看全部进程状态(我最常用的命令)
supervisorctl status
# 输出示例:
# flask_app RUNNING pid 1234, uptime 2 days
# celery_worker FATAL Exited too quickly (process log may have details)
# 过滤特定进程状态(排查问题神器)
supervisorctl status | grep FATAL
# 查看进程详细日志
supervisorctl tail -f flask_app stderr # 实时查看错误日志
很多人不知道stop和signal的区别:
bash复制# 温和停止(发送SIGTERM)
supervisorctl stop flask_app
# 强制停止(发送SIGKILL)
supervisorctl signal SIGKILL flask_app
# 批量操作进程组
supervisorctl start group:web_servers
实测发现restart操作有个隐藏特性:它会先执行stop,等进程完全退出后再start。如果进程卡死无法停止,可以这样处理:
bash复制supervisorctl signal SIGKILL flask_app
supervisorctl start flask_app
部署Gunicorn+Flask应用时,需要实现零停机更新。这是我的独家方案:
ini复制[program:flask_app]
command=/path/to/gunicorn --reload
stopasgroup=true # 关键!确保worker进程也被终止
killasgroup=true
操作流程:
supervisorctl restart flask_app用supervisorctl管理Celery beat的经典配置:
ini复制[program:celery_beat]
command=/path/to/celery -A proj beat
startsecs=10 # 给足启动时间
autorestart=unexpected # 只有意外退出才重启
遇到过beat进程假死但状态仍显示RUNNING的情况,解决方案是增加健康检查:
bash复制*/5 * * * * supervisorctl status celery_beat | grep -q RUNNING || supervisorctl restart celery_beat
内存泄漏检测:某次发现supervisord本身内存持续增长,最后发现是日志文件未做切割。解决方案:
ini复制[supervisord]
logfile=/var/log/supervisord.log
logfile_maxbytes=50MB # 限制单个日志大小
logfile_backups=10 # 保留10个备份
权限陷阱:用root启动的进程无法被普通用户管理。正确做法:
bash复制sudo chmod 755 /var/run/supervisor.sock
sudo chown user:user /var/log/flask_app*.log
启动顺序问题:MySQL未启动导致应用失败。解决方案是设置优先级:
ini复制[program:mysql]
priority=100 # 数值越小优先级越高
[program:flask_app]
priority=500
startsecs=60 # 给足依赖服务启动时间