进程管理备忘录(supervisor)

Supervisor 核心价值

  1. 进程保活:异常退出自动重启
  2. 日志管理:集中收集与轮转切割
  3. 服务编排:多进程启停顺序控制
  4. 权限隔离:以指定用户身份运行
  5. 状态监控:提供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

启动顺序控制

  1. 先执行 init_db (priority 值小优先)
  2. 主应用监测 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 status

2. # 优雅重启
 supervisorctl restart app

3. # 强制停止
 supervisorctl stop app
 kill -9 $(ps -ef | grep app | grep -v grep | awk '{print $2}')

4. # 回滚版本
 rsync -av /backup/app_v1/ /opt/app/

5. # 重新启动
 supervisorctl start app

十、注意事项

  1. 权限控制
  • 禁止使用root运行业务进程
  • Log目录设置 chmod 700 /var/log/supervisor
  1. 资源限制
[program:workers]
minfds=65535# 文件描述符限制
minprocs=20000 # 进程数限制
  1. 不要使用场景
  • 需要依赖系统启动顺序的服务
  • 必须保证单实例的系统核心组件
  • 需要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 Celery

app = 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
posted @   Mugetsukun  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示