Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> 電腦軟體教學 >> 伺服器技術 >> 關於伺服器

Linux VPS 記憶體/負載監控自動重啟服務 Shell 腳本實戰 (含 crontab 部署)

編輯:關於伺服器

VPS 資源有限 (1-2GB 記憶體常見),MySQL、PHP-FPM、Nginx 等服務在流量突增或記憶體洩漏時極易耗盡資源導致當機。本文提供兩支生產級監控腳本:依比例監控 適合容器/動態環境,依絕對值監控 適合固定規格 VPS,並詳細說明參數調校、部署驗證、常見錯誤排查。

腳本一:依記憶體佔用比例 + 系統負載監控 (auto_reboot.sh)

適用場景: 容器、雲主機、記憶體總量可變環境。當服務記憶體佔比超過閾值 或 系統負載過高 時,重啟指定服務。

#!/bin/bash
# auto_reboot.sh - 依比例監控版
# 部署路徑建議:/usr/local/sbin/auto_reboot.sh
# crontab: * * * * * /usr/local/sbin/auto_reboot.sh >/dev/null 2>&1

# ========== 使用者配置區 ==========
# 服務記憶體佔用最大百分比 (超過則重啟該服務)
PID_MEM_MAX=85
# 系統負載 1 分鐘平均值最大值 (超過則重啟服務)
SYS_LOAD_MAX=3.0
# 監控的服務名稱 (systemd service name 或進程關鍵字,空格分隔)
NAME_LIST="php-fpm mysqld nginx"
# 記憶體資訊來源 (通常免改)
MEM_INFO="/proc/meminfo"
# ====================================

# 取得系統總記憶體 (KB)
TOTAL_MEM=$(awk '/MemTotal/ {print $2}' $MEM_INFO)
# 取得系統可用記憶體 (KB) - 含 buffers/cache
AVAIL_MEM=$(awk '/MemAvailable/ {print $2}' $MEM_INFO)
# 若無 MemAvailable (舊核心),退而求其次用 MemFree+Buffers+Cached
if [ -z "$AVAIL_MEM" ]; then
    FREE_MEM=$(awk '/MemFree/ {print $2}' $MEM_INFO)
    BUFFERS=$(awk '/Buffers/ {print $2}' $MEM_INFO)
    CACHED=$(awk '/^Cached/ {print $2}' $MEM_INFO)
    AVAIL_MEM=$((FREE_MEM + BUFFERS + CACHED))
fi

# 計算系統記憶體使用率 (%)
MEM_USAGE_PCT=$(awk "BEGIN {printf \"%.0f\", (($TOTAL_MEM - $AVAIL_MEM) * 100) / $TOTAL_MEM}")

# 取得系統負載 (1 分鐘)
SYS_LOAD=$(awk '{print $1}' /proc/loadavg)

# 判斷是否觸發重啟條件
TRIGGER=0
if [ $MEM_USAGE_PCT -ge $PID_MEM_MAX ]; then
    echo "[$(date)] Memory usage ${MEM_USAGE_PCT}% >= ${PID_MEM_MAX}%, triggering restart"
    TRIGGER=1
fi
if (( $(echo "$SYS_LOAD > $SYS_LOAD_MAX" | bc -l) )); then
    echo "[$(date)] System load ${SYS_LOAD} > ${SYS_LOAD_MAX}, triggering restart"
    TRIGGER=1
fi

if [ $TRIGGER -eq 1 ]; then
    for SVC in $NAME_LIST; do
        echo "[$(date)] Restarting service: $SVC"
        systemctl restart $SVC 2>/dev/null || service $SVC restart 2>/dev/null
        sleep 2
    done
fi

腳本二:依剩餘記憶體絕對值 + 負載監控 (check_reboot.sh)

適用場景: 固定規格 VPS (如 1GB/2GB 記憶體),根據實際剩餘 MB 數決定動作。

#!/bin/bash
# check_reboot.sh - 依絕對值監控版
# 部署路徑建議:/usr/local/sbin/check_reboot.sh
# crontab: * * * * * /usr/local/sbin/check_reboot.sh >/dev/null 2>&1

# ========== 使用者配置區 ==========
# 最小剩餘記憶體 (MB) - 低於此值視為危險
FREE_MEM_MIN=100
# 系統負載 1 分鐘最大值
SYS_LOAD_MAX=3.0
# 重啟服務所需最小剩餘記憶體 (MB) - 低於此值不嘗試重啟(防止重啟失敗更糟)
RESTART_FREE_MEM_MIN=200
# 監控的服務名稱
NAME_LIST="httpd mysqld php-fpm nginx"
# ====================================

# 取得剩餘記憶體 (MB)
FREE_MEM_MB=$(awk '/MemAvailable/ {printf "%.0f", $2/1024}' /proc/meminfo)
if [ -z "$FREE_MEM_MB" ] || [ $FREE_MEM_MB -eq 0 ]; then
    FREE_MEM_MB=$(awk '/MemFree/ {free=$2} /Buffers/ {buf=$2} /^Cached/ {cac=$2} END {printf "%.0f", (free+buf+cac)/1024}' /proc/meminfo)
fi

# 取得系統負載
SYS_LOAD=$(awk '{print $1}' /proc/loadavg)

echo "[$(date)] FreeMem=${FREE_MEM_MB}MB Load=${SYS_LOAD}"

# 記憶體極度不足,不嘗試重啟,僅記錄告警 (需人工/監控系統介入)
if [ $FREE_MEM_MB -lt $FREE_MEM_MIN ]; then
    echo "[$(date)] CRITICAL: Free memory ${FREE_MEM_MB}MB < ${FREE_MEM_MIN}MB, skipping auto-restart to avoid OOM"
    # 這裡可加入發送告警郵件/釘釘/Telegram 邏輯
    exit 1
fi

# 負載過高或記憶體偏低但尚可重啟
TRIGGER=0
if (( $(echo "$SYS_LOAD > $SYS_LOAD_MAX" | bc -l) )); then
    echo "[$(date)] Load ${SYS_LOAD} > ${SYS_LOAD_MAX}"
    TRIGGER=1
fi
if [ $FREE_MEM_MB -lt $RESTART_FREE_MEM_MIN ]; then
    echo "[$(date)] FreeMem ${FREE_MEM_MB}MB < RestartMin ${RESTART_FREE_MEM_MIN}MB"
    TRIGGER=1
fi

if [ $TRIGGER -eq 1 ]; then
    for SVC in $NAME_LIST; do
        echo "[$(date)] Restarting: $SVC"
        systemctl restart $SVC 2>/dev/null || service $SVC restart 2>/dev/null
        sleep 3
    done
fi

部署與驗證步驟

  1. 建立腳本檔案:
    mkdir -p /usr/local/sbin
    vim /usr/local/sbin/auto_reboot.sh   # 貼上腳本一內容
    vim /usr/local/sbin/check_reboot.sh # 貼上腳本二內容
    chmod +x /usr/local/sbin/auto_reboot.sh /usr/local/sbin/check_reboot.sh
  2. 修改配置參數: 根據 VPS 實際規格調整閾值 (見腳本頂部配置區)。
  3. 確認 bc 已安裝 (浮點比較需用):
    which bc || yum -y install bc  # CentOS/RHEL
    # apt-get install -y bc         # Debian/Ubuntu
  4. 測試腳本語法與執行:
    bash -n /usr/local/sbin/auto_reboot.sh
    bash -n /usr/local/sbin/check_reboot.sh
    /usr/local/sbin/auto_reboot.sh     # 應無輸出 (正常情況)
    /usr/local/sbin/check_reboot.sh    # 輸出當前資源狀態
  5. 加入 crontab (每分鐘檢查):
    crontab -e
    # 每分鐘執行一次,標準輸出/錯誤導向 /dev/null (或記錄檔)
    * * * * * /usr/local/sbin/auto_reboot.sh >>/var/log/auto_reboot.log 2>&1
    # * * * * * /usr/local/sbin/check_reboot.sh >>/var/log/check_reboot.log 2>&1

    注意: crontab 中 * 之間用 空格 分隔,非 Tab;路徑必須為絕對路徑。

  6. 驗證定時任務生效:
    tail -f /var/log/auto_reboot.log
    # 觀察每分鐘是否有紀錄

參數調校建議

參數1GB VPS 建議2GB VPS 建議4GB+ VPS 建議
PID_MEM_MAX80%85%90%
SYS_LOAD_MAX1.0 (單核) / 2.0 (雙核)2.0 / 4.0核心數 * 0.7
FREE_MEM_MIN80MB150MB300MB
RESTART_FREE_MEM_MIN150MB300MB500MB

進階擴充:整合告警通知

在腳本 TRIGGER=1 區塊或 CRITICAL 區塊加入:

# 發送 Telegram Bot 通知
curl -s -X POST "https://api.telegram.org/bot/sendMessage" \
     -d chat_id= \
     -d text="🚨 VPS Alert: $(hostname) - Service restart triggered. Load: $SYS_LOAD, FreeMem: ${FREE_MEM_MB}MB" \
     >/dev/null

自動重啟腳本是**「止血」而非「治本」**。長期穩定仍需:優化 SQL 查詢、啟用 PHP OpCache、配置 Nginx fastcgi/fastcgi_cache、限制並發連線、升級硬體資源。建議將腳本納入基礎設施即代碼管理,配合監控系統 (Prometheus+Alertmanager) 實現「自動止血 + 人工根治」閉環。

Copyright © Windows教程網 All Rights Reserved