Supervisor 是 Python 寫的進程管理工具,廣泛用於生產環境管理長期運行的服務進程。本文涵蓋安裝、配置、核心功能演示與進階監控整合。
# 安裝
pip install supervisor
# 生成預設配置檔
echo_supervisord_conf > /etc/supervisord.conf
# 目錄結構
supervisord # 守護進程,管理子進程
supervisorctl # 命令列客戶端,控制進程
Web UI # 可選的 Web 管理介面
; /etc/supervisord.conf 關鍵段落
[unix_http_server]
file=/var/run/supervisor.sock ; supervisorctl 通訊 socket
chmod=0700
[supervisord]
logfile=/var/log/supervisord.log
pidfile=/var/run/supervisord.pid
childlogdir=/var/log/supervisor
nodaemon=false ; 背景運行
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock
; --- 程式定義範例 ---
[program:my_web_app]
command=/home/user/venv/bin/gunicorn -w 4 myapp:app
directory=/home/user/myproject
user=www-data
autostart=true
autorestart=true ; 關鍵:異常退出自動重啟
startsecs=3 ; 啟動 3 秒後視為成功
stderr_logfile=/var/log/myapp_err.log
stdout_logfile=/var/log/myapp_out.log
environment=PYTHONPATH="/home/user/myproject",ENV="production"
redirect_stderr=true ; 合併 stderr 到 stdout
# /home/user/daemon.py
#!/usr/bin/env python
import time
while True:
with open("log", "a") as f:
f.write(str(time.time()) + "\n")
time.sleep(1)
[program:daemon]
command=/home/user/daemon.py
autorestart=true
stdout_logfile=/var/log/daemon.log
# 啟動 supervisord
supervisord -c /etc/supervisord.conf
# 進入控制台
supervisorctl -c /etc/supervisord.conf
# 命令範例
supervisor> status
daemon RUNNING pid 1234, uptime 0:00:01
supervisor> stop daemon
daemon: stopped
supervisor> start daemon
daemon: started
supervisor> restart daemon
daemon: stopped
daemon: started
# 測試自動重啟:手動 kill 進程
supervisor> status
daemon RUNNING pid 1234, uptime 0:00:10
supervisor> quit
$ kill 1234
$ tail -f /var/log/daemon.log
# 發現新 PID 繼續寫入日誌,證明自動重啟生效
; supervisoci.conf 新增
[inet_http_server]
port=0.0.0.0:9001
username=admin
password=secure_password
瀏覽器訪問 https://server_ip:9001 即可查看進程狀態、日誌、執行控制。
[group:web_services]
programs=web_app,celery_worker,celery_beat
priority=999
批次控制:supervisorctl stop web_services:*
[eventlistener:crash_notifier]
command=/home/user/scripts/crash_alert.py
events=PROCESS_STATE_FATAL,PROCESS_STATE_EXITED
配合郵件/Slack 通知實現故障即時告警。
# Dockerfile
FROM python:3.9-slim
RUN pip install supervisor gunicorn
COPY supervisord.conf /etc/supervisord.conf
COPY . /app
WORKDIR /app
CMD ["supervisord", "-n", "-c", "/etc/supervisord.conf"]
注意:Docker 中建議 nodaemon=true 並在前景運行,配合 --init 處理殭屍進程。
| 現象 | 原因 | 解決 |
|---|---|---|
| 進程反覆重啟 (BACKOFF) | 啟動腳本立即退出 | 檢查腳本邏輯、startsecs 設定、依賴服務就緒 |
| 日誌不輸出 | Python 緩衝區 | 啟動加 -u 或 PYTHONUNBUFFERED=1 |
| 權限錯誤 | user 參數與檔案權限不符 | 確保執行用戶有讀寫權限 |