#!/bin/bash # web_server.py 进程守护脚本:崩溃自动重启,带退避和重启上限。 # # 用法: # bash scripts/supervise.sh # 用 python3 启动 # PYTHON=./.venv/bin/python bash scripts/supervise.sh # 指定 Python(venv) # # 行为: # - web_server 崩溃(非 0/130 退出码)→ 等待 BACKOFF_MIN 秒自动重启 # - 重启窗口(RESTART_WINDOW 秒)内超过 MAX_RESTARTS 次 → 停止(防崩溃死循环) # - 正常退出(Ctrl+C=130 或 code=0)→ 守护结束 # - 日志写到 logs/supervise.log # # 生产无人值守建议配合 Docker 的 restart: unless-stopped 或 systemd 一起用。 cd "$(dirname "$0")/.." PYTHON="${PYTHON:-python3}" mkdir -p logs MAX_RESTARTS="${MAX_RESTARTS:-10}" # 窗口内最大重启次数 RESTART_WINDOW="${RESTART_WINDOW:-300}" # 重启窗口(秒) BACKOFF_MIN="${BACKOFF_MIN:-2}" # 重启前等待(秒) restarts=0 window_start=$(date +%s) echo "[$(date '+%F %T')] 进程守护启动,python=$PYTHON" while true; do echo "[$(date '+%F %T')] 启动 web_server.py..." "$PYTHON" web_server.py >> logs/supervise.log 2>&1 code=$? echo "[$(date '+%F %T')] web_server 退出,code=$code" # 0 = 正常结束;130 = Ctrl+C(SIGINT)→ 手动停止,守护结束 if [ "$code" -eq 0 ] || [ "$code" -eq 130 ]; then echo "[$(date '+%F %T')] 正常退出,守护进程结束" break fi # 滑动窗口计数 now=$(date +%s) if [ $((now - window_start)) -gt "$RESTART_WINDOW" ]; then window_start=$now restarts=0 fi restarts=$((restarts + 1)) if [ "$restarts" -gt "$MAX_RESTARTS" ]; then echo "[$(date '+%F %T')] ${RESTART_WINDOW}s 内崩溃超过 ${MAX_RESTARTS} 次,停止守护(可能配置/环境问题)" break fi echo "[$(date '+%F %T')] ${BACKOFF_MIN}s 后重启 (窗口内第 ${restarts} 次)" sleep "$BACKOFF_MIN" done