Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學

Linux 進程監控自動重啟 Shell 腳本編寫實戰(以 Tomcat 為例)

編輯:Linux 系統常見問題解答

需求場景

生產環境中 Java 應用(如 Tomcat)偶發記憶體洩漏、死鎖或 OOM 導致進程掛掉。需要一個輕量級的 Shell 腳本,定期檢測進程狀態,自動重啟並記錄日誌,作為監控系統的補充而非替代。

完整腳本代碼

#!/bin/bash
# ==========================================
# Tomcat 進程監控自動重啟腳本
# 作者:系統運維團隊
# 版本:v1.2
# 依賴:ps, grep, awk, kill, sleep
# ==========================================

set -euo pipefail

# ========= 設定區 =========
APP_NAME="tomcat"
APP_HOME="/opt/tomcat"
START_SCRIPT="$APP_HOME/bin/startup.sh"
SHUTDOWN_SCRIPT="$APP_HOME/bin/shutdown.sh"
PID_FILE="$APP_HOME/tomcat.pid"
LOG_FILE="/var/log/tomcat_monitor.log"
CHECK_INTERVAL=30
MAX_RESTART_ATTEMPTS=3
# ============================

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}

get_pid() {
    # 精確匹配 java 進程中的 catalina.base
    pgrep -f "catalina.base=$APP_HOME" | head -1
}

cleanup_work_dir() {
    log "清理工作目錄: $APP_HOME/work/*"
    rm -rf "$APP_HOME"/work/* 2>/dev/null
    rm -rf "$APP_HOME"/temp/* 2>/dev/null
}

start_app() {
    log "啟動 $APP_NAME ..."
    if [[ -f "$START_SCRIPT" ]]; then
        cd "$APP_HOME"
        nohup "$START_SCRIPT" >> "$APP_HOME/logs/catalina.out" 2>&1 &
        sleep 3
    else
        log "錯誤:找不到啟動腳本 $START_SCRIPT"
        return 1
    fi
}

stop_app() {
    local pid=$1
    log "嘗試優雅關閉 PID: $pid"
    if [[ -f "$SHUTDOWN_SCRIPT" ]]; then
        "$SHUTDOWN_SCRIPT" 2>/dev/null
        sleep 5
    fi
    
    # 檢查是否還在運行
    if kill -0 "$pid" 2>/dev/null; then
        log "優雅關閉失敗,強制終止 PID: $pid"
        kill -9 "$pid"
        sleep 2
    fi
}

# ========= 主邏輯 =========
log "=== Tomcat 監控啟動 ==="

restart_count=0
last_restart_time=0

while true; do
    PID=$(get_pid)
    
    if [[ -z "$PID" ]]; then
        log "偵測到 $APP_NAME 進程不存在"
        
        # 防止頻繁重啟(30分鐘內最多3次)
        current_time=$(date +%s)
        if (( current_time - last_restart_time > 1800 )); then
            restart_count=0
        fi
        
        if (( restart_count < MAX_RESTART_ATTEMPTS )); then
            cleanup_work_dir
            start_app
            ((restart_count++))
            last_restart_time=$current_time
            log "重啟嘗試 $restart_count/$MAX_RESTART_ATTEMPTS"
        else
            log "錯誤:短時間內重啟次數過多,停止嘗試,請人工介入"
            # 可在此加入告警發送:郵件、釘釘、企業微信等
        fi
    else
        # 進程存在,重置計數器
        if (( restart_count > 0 )); then
            log "$APP_NAME 運行正常,重置重啟計數器"
            restart_count=0
        fi
    fi
    
    sleep "$CHECK_INTERVAL"
done

關鍵技術點解析

技術點說明
pgrep -f "catalina.base=..."精確匹配 Tomcat 進程,避免誤殺其他 Java 進程
set -euo pipefail嚴格模式:變量未定義報錯、命令失敗即退出、管道失敗傳遞
nohup ... &後台運行且免疫 SIGHUP,配合輸出重導向
優雅關閉 → 強制殺掉先嘗試 shutdown.sh 釋放資源,失敗再 kill -9
工作目錄清理清除 work/temp 目錄防止 JSP 編譯殘留導致啟動異常
頻率限制30分鐘內最多3次重啟,防止故障風暴

部署與運行

1. 安裝腳本

sudo tee /usr/local/bin/tomcat_monitor.sh > /dev/null <<'EOF'
# 腳本內容...
EOF
sudo chmod +x /usr/local/bin/tomcat_monitor.sh

2. Systemd 服務化(推薦)

sudo tee /etc/systemd/system/tomcat-monitor.service > /dev/null <<'EOF'
[Unit]
Description=Tomcat Process Monitor
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/tomcat_monitor.sh
Restart=always
RestartSec=10
User=tomcat
Group=tomcat
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now tomcat-monitor

3. 傳統 nohup 方式(不推薦生產)

nohup /usr/local/bin/tomcat_monitor.sh > /dev/null 2>&1 &

進階增強建議

  • 健康檢查:整合 HTTP 請求檢查 curl -f https://localhost:8080/health 而非僅檢查進程存活
  • 指標收集:輸出 Prometheus 格式指標供 Grafana 監控
  • 告警通知:整合 Webhook 發送至釘釘/企業微信/Slack
  • 日誌輪轉:配置 logrotate 管理監控日誌
  • 鎖機制:使用 flock 防止多實例並發運行

總結

這個 Shell 腳本雖簡單,但涵蓋了進程檢測、優雅重啟、資源清理、頻率限制、日誌記錄等生產級要素。實際部署時建議配合 Systemd 管理,並根據業務特性加入 HTTP 健康檢查與告警通知,構建完整的自愈體系。

Copyright © Windows教程網 All Rights Reserved