Supervisor 核心价值
- 进程保活:异常退出自动重启
- 日志管理:集中收集与轮转切割
- 服务编排:多进程启停顺序控制
- 权限隔离:以指定用户身份运行
- 状态监控:提供Web/CLI监控界面
一、基础配置
1. 最小化配置
[program:webapp]
command=/opt/app/bin/gunicorn -w 4 app:app
directory=/opt/app
user=appuser
autostart=true
autorestart=unexpected
stopsignal=TERM
stdout_logfile=/var/log/webapp.log
redirect_stderr=true
参数解析:
autorestart=unexpected
:仅在非正常退出时重启stopsignal=TERM
:优雅终止信号redirect_stderr
:错误输出合并到stdout
2. 进程分组管理
[group:microservices]
programs=svc1,svc2,svc3
priority=999
操作命令:
supervisorctl start microservices:
supervisorctl stop microservices:*
二、生产环境实践
3. 优雅关闭配合
[program:celery]
command=/opt/app/bin/celery -A tasks worker
stopwaitsecs=300
killasgroup=true
stopasgroup=true
关键参数:
stopwaitsecs
:等待进程自行退出的超时时间killasgroup
:向整个进程组发送信号
4. 日志轮转配置
[program:task_processor]
stdout_logfile=/var/log/task.log
stdout_logfile_maxbytes=100MB
stdout_logfile_backups=10
stdout_capture_maxbytes=0
日志维护策略:
- 最多保留10份日志
- 单文件上限100MB
- 禁用日志内存缓冲
三、高级应用场景
5. 动态环境变量
[program:api_server]
command=/opt/app/start.sh
environment=
NODE_ENV="prod",
REDIS_HOST="%(ENV_REDIS_HOST)s",
SECRET_KEY="%(ENV_API_KEY)s"
启动命令:
ENV_REDIS_HOST=10.0.0.5 ENV_API_KEY=xxxx supervisord
6. 多进程启动顺序
[program:init_db]
command=/opt/app/bin/init_db.sh
priority=100
autorestart=false[program:main_app]
command=/opt/app/bin/start_app.sh
priority=200
startsecs=30
startretries=3
depends_on=init_db
启动顺序控制:
- 先执行 init_db (priority 值小优先)
- 主应用监测 init_db 完成才开始
7. 容器化部署方案
# supervisor.conf
[supervisord]
nodaemon=true
logfile=/dev/stdout
logfile_maxbytes=0[program:app]
command=python /app/main.py
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
容器操作:
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor.conf"]
四、安全强化配置
8. Web控制台安全
[inet_http_server]
port=10.0.0.1:9001
username=admin
password=sha1:7b4d4a5b5e7a:9933d6ddf7a9d1add043a9482a9f1082e929d3c
密码生成:
echo 'mypassword' | openssl sha1
9. 文件权限隔离
[program:sensitive_job]
user=isolated
umask=0077
directory=/opt/secure
防御策略:
- 专用低权限用户运行
- 目录权限 700
- 日志独立存储
五、维护与排错
10. 信号与状态解读
信号 | 用途 | 示例命令 |
---|---|---|
SIGHUP | 重载配置 | supervisorctl reload |
SIGTERM | 正常关闭 | supervisorctl shutdown |
SIGQUIT | 强制关闭 | kill -QUIT pid |
进程状态表:
状态 | 含义 | 处理措施 |
---|---|---|
FATAL | 配置错误 | 检查日志/配置文件 |
BACKOFF | 频繁重启 | 查看进程退出代码 |
STOPPED | 手动停止 | 检查依赖项 |
11. 僵尸进程处理
supervisorctl stop all
ps -ef | grep defunct | awk '{print $3}' | xargs kill -9
supervisorctl start all
六、企业级监控指标
Prometheus Exporter 配置:
[program:supervisor_exporter]
command=/opt/exporter/supervisor_exporter --telemetry.addr=:9002
autostart=true
关键监控项:
supervisor_process_status
进程状态 (0=RUNNING)supervisor_restart_count
进程重启次数supervisor_up
Supervisor自身健康状态
七、性能调优指南
12. 内存限制防护
[program:memory_intensive]
command=/opt/app/bigdata_processor
stopasgroup=true
killasgroup=true
environment=MEMORY_LIMIT="80%"
配套监控脚本:
#!/bin/bash
if [[ $(ps -o rss= $(cat /var/run/app.pid)) -gt 8000000 ]]; then
supervisorctl restart memory_intensive
fi
八、与Systemd对比实践
Supervisor vs Systemd 选型矩阵
需求场景 | Supervisor | Systemd |
---|---|---|
进程日志管理 | ✔️ 自动收集 | 需单独配置 |
多进程依赖管理 | ✔️ 灵活编排 | 需多个unit文件 |
非root启动进程 | ✔️ 原生支持 | 需用户服务文件 |
系统级服务 | ❌ 不适合 | ✔️ 首选方案 |
Docker容器内 | ✔️ 轻量管理 | ❌ 过于臃肿 |
九、灾难恢复演练
场景:服务进程陷入死循环
1. # 查看异常进程supervisorctl status2. # 优雅重启supervisorctl restart app3. # 强制停止supervisorctl stop appkill -9 $(ps -ef | grep app | grep -v grep | awk '{print $2}')4. # 回滚版本rsync -av /backup/app_v1/ /opt/app/5. # 重新启动supervisorctl start app
十、注意事项
- 权限控制
- 禁止使用root运行业务进程
- Log目录设置
chmod 700 /var/log/supervisor
- 资源限制
[program:workers]
minfds=65535# 文件描述符限制
minprocs=20000 # 进程数限制
- 不要使用场景
- 需要依赖系统启动顺序的服务
- 必须保证单实例的系统核心组件
- 需要cgroups隔离的资源管理
实践
实践示例:使用 Supervisor 管理一个 Flask 应用
步骤 1:安装 Supervisor
sudo apt-get update
sudo apt-get install -y supervisor
步骤 2:创建 Flask 应用
在 /opt/myapp
目录下创建一个简单的 Flask 应用:
# app.py
from flask import Flask
app = Flask(__name__)@app.route('/')
def home():return "Hello, Supervisor!"
步骤 3:配置 Supervisor
创建配置文件 /etc/supervisor/conf.d/myapp.conf
:
[program:myapp]
command=/usr/bin/python3 /opt/myapp/app.py
directory=/opt/myapp
user=myuser
autostart=true
autorestart=true
stdout_logfile=/var/log/myapp.log
redirect_stderr=true
步骤 4:重新加载 Supervisor 配置
sudo supervisorctl reload
步骤 5:启动服务
sudo supervisorctl start myapp
步骤 6:验证服务状态
sudo supervisorctl status myapp
步骤 7:访问应用
在浏览器中访问 http://localhost:5000
,应看到 "Hello, Supervisor!"。
步骤 8:停止服务
sudo supervisorctl stop myapp
步骤 9:重启服务
sudo supervisorctl restart myapp
步骤 10:查看日志
tail -f /var/log/myapp.log
实践示例:使用 Supervisor 管理 Celery 任务队列
步骤 1:安装 Celery 和 Supervisor
sudo apt-get update
sudo apt-get install -y supervisor
pip3 install celery
步骤 2:创建 Celery 任务
在 /opt/celery
目录下创建任务文件 tasks.py
:
from celery import Celeryapp = Celery('tasks', broker='redis://localhost:6379/0')@app.task
def add(x, y):return x + y
步骤 3:配置 Supervisor
创建配置文件 /etc/supervisor/conf.d/celery.conf
:
[program:celery]
command=/usr/bin/celery -A tasks worker --loglevel=INFO
directory=/opt/celery
user=celeryuser
autostart=true
autorestart=unexpected
stdout_logfile=/var/log/celery.log
redirect_stderr=true
步骤 4:重新加载 Supervisor 配置
sudo supervisorctl reload
步骤 5:启动 Celery 服务
sudo supervisorctl start celery
步骤 6:验证服务状态
sudo supervisorctl status celery
步骤 7:测试任务
celery -A tasks call add 4 5
步骤 8:停止服务
sudo supervisorctl stop celery
步骤 9:重启服务
sudo supervisorctl restart celery
步骤 10:查看日志
tail -f /var/log/celery.log
实践示例:使用 Supervisor 管理 Nginx 和 Gunicorn
步骤 1:安装 Nginx 和 Gunicorn
sudo apt-get update
sudo apt-get install -y nginx python3-gunicorn supervisor
步骤 2:创建 Flask 应用
在 /opt/webapp
目录下创建 app.py
:
from flask import Flask
app = Flask(__name__)@app.route('/')
def home():return "Hello, Supervisor!"
步骤 3:配置 Gunicorn
创建配置文件 /etc/supervisor/conf.d/webapp.conf
:
[program:webapp]
command=/usr/bin/gunicorn -w 4 -b 0.0.0.0:8000 app:app
directory=/opt/webapp
user=webuser
autostart=true
autorestart=unexpected
stdout_logfile=/var/log/webapp.log
redirect_stderr=true
步骤 4:配置 Nginx
创建 Nginx 配置文件 /etc/nginx/sites-available/webapp
:
server {listen 80;server_name localhost;location / {proxy_pass http://localhost:8000;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}
启用配置并重启 Nginx:
sudo ln -s /etc/nginx/sites-available/webapp /etc/nginx/sites-enabled/
sudo systemctl restart nginx
步骤 5:重新加载 Supervisor 配置
sudo supervisorctl reload
步骤 6:启动服务
sudo supervisorctl start webapp
步骤 7:验证服务状态
sudo supervisorctl status webapp
步骤 8:访问应用
在浏览器中访问 http://localhost
,应看到 "Hello, Supervisor!"。
步骤 9:停止服务
sudo supervisorctl stop webapp
步骤 10:重启服务
sudo supervisorctl restart webapp
步骤 11:查看日志
tail -f /var/log/webapp.log