#!/bin/bash # 清理舊的 gunicorn momo 進程(改進版,增加超時和錯誤處理) # V-Fix 2026-01-14: 修復在高負載下卡住的問題 set -e # 遇到錯誤立即退出 # 設定超時時間(秒) TIMEOUT=10 MAX_ATTEMPTS=3 # 日誌函數 log() { echo "[$(/usr/bin/date '+%Y-%m-%d %H:%M:%S')] $1" } log "開始清理舊的 gunicorn 進程" # 查找所有 gunicorn 進程(排除當前腳本) PIDS=$(/usr/bin/pgrep -f 'gunicorn.*app:app' || true) if [ -z "$PIDS" ]; then log "沒有發現舊的 gunicorn 進程" exit 0 fi log "發現以下 gunicorn 進程: $PIDS" # 嘗試優雅終止(SIGTERM) for attempt in $(/usr/bin/seq 1 $MAX_ATTEMPTS); do log "嘗試 #$attempt: 發送 SIGTERM 信號" for pid in $PIDS; do if /usr/bin/ps -p "$pid" > /dev/null 2>&1; then /usr/bin/kill -TERM "$pid" 2>/dev/null || true fi done # 等待進程退出 WAIT_TIME=0 ALL_KILLED=true while [ $WAIT_TIME -lt $TIMEOUT ]; do ALL_KILLED=true for pid in $PIDS; do if /usr/bin/ps -p "$pid" > /dev/null 2>&1; then ALL_KILLED=false break fi done if [ "$ALL_KILLED" = true ]; then log "所有進程已優雅退出" exit 0 fi /usr/bin/sleep 1 WAIT_TIME=$((WAIT_TIME + 1)) done log "部分進程未能在 ${TIMEOUT} 秒內退出,重試..." done # 如果優雅終止失敗,強制終止(SIGKILL) log "優雅終止失敗,使用 SIGKILL 強制終止" for pid in $PIDS; do if ps -p "$pid" > /dev/null 2>&1; then log "強制終止進程 $pid" /usr/bin/kill -9 "$pid" 2>/dev/null || true fi done # 最後確認 /usr/bin/sleep 2 REMAINING=$(/usr/bin/pgrep -f 'gunicorn.*app:app' | /usr/bin/wc -l) if [ "$REMAINING" -gt 0 ]; then log "警告:仍有 $REMAINING 個 gunicorn 進程殘留" exit 1 else log "所有 gunicorn 進程已清理完成" exit 0 fi