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

Linux VPS 依系統負載自動重啟 Web 服務腳本實戰部署

編輯:關於伺服器

背景:VPS 資源受限易遭 DDOS/CC 攻擊癱瘓

  • VPS = 獨立伺服器切分,CPU/記憶體/IO 有硬性配額上限
  • 攻擊洪峰 → 記憶體耗盡 → 系統負載飆升 → HTTP 服務無回應 → 業務中斷
  • 完整防禦體系昂貴 (WAF/高防 IP/清洗中心),輕量級自動重啟為**最後一道防線**

系統負載核心概念

  • `uptime` / `w` / `top` 輸出:`load average: 0.52, 0.58, 0.59` (1/5/15 分鐘)
  • **負載 = 運行隊列中平均進程數** (可執行 + 不可中斷睡眠)
  • 單核心:負載 1.0 = 100% 滿載;雙核心:負載 2.0 = 100% 滿載
  • **判斷依據**:`負載 > 核心數 × 0.7` 視為高負載,`> 核心數 × 1.0` 視為過載

自動重啟腳本 (Apache 範例,支援 Nginx/PHP-FPM 微調)

#!/bin/bash
# /root/checkload.sh
# crontab: */2 * * * * root /root/checkload.sh >> /root/checkload.log 2>&1

# === 可調參數 ===
MAX_LOAD=5                    # 觸發重啟的負載閾值 (單核建議 3-5,多核乘以核心數)
SERVICE_NAME="httpd"          # 服務名稱:httpd / nginx / php-fpm
CHECK_INTERVAL=2              # 重啟後檢查間隔 (秒)
MAX_RETRY=3                   # 最大重試次數

# === 核心邏輯 ===
CURRENT_LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
DATE_STR=$(date '+%Y-%m-%d %H:%M:%S')

echo "$DATE_STR [INFO] Current load: $CURRENT_LOAD (threshold: $MAX_LOAD)" >> /root/checkload.log

# 使用 bc 比較浮點數
if (( $(echo "$CURRENT_LOAD > $MAX_LOAD" | bc -l) )); then
    echo "$DATE_STR [ALERT] Load $CURRENT_LOAD > $MAX_LOAD, restarting $SERVICE_NAME..." >> /root/checkload.log
    
    # 強制殺掉殘留進程
    pkill -9 $SERVICE_NAME
    sleep 5
    
    # 嘗試啟動,最多重試 MAX_RETRY 次
    for i in $(seq 1 $MAX_RETRY); do
        systemctl start $SERVICE_NAME 2>/dev/null || service $SERVICE_NAME start
        sleep $CHECK_INTERVAL
        RUNNING=$(pgrep -c $SERVICE_NAME)
        if [ "$RUNNING" -gt 0 ]; then
            echo "$DATE_STR [OK] $SERVICE_NAME restarted successfully (pid count: $RUNNING)" >> /root/checkload.log
            break
        else
            echo "$DATE_STR [WARN] Attempt $i/$MAX_RETRY failed, retrying..." >> /root/checkload.log
        fi
    done
    
    # 所有重試失敗
    if [ "$(pgrep -c $SERVICE_NAME)" -eq 0 ]; then
        echo "$DATE_STR [CRITICAL] $SERVICE_NAME failed to start after $MAX_RETRY attempts!" >> /root/checkload.log
        # 可在此加入告警通知:mail、webhook、钉钉、Telegram
    fi
else
    # 負載正常,但服務意外停止 → 守護進程功能
    if [ "$(pgrep -c $SERVICE_NAME)" -eq 0 ]; then
        echo "$DATE_STR [GUARD] Load normal but $SERVICE_NAME not running, starting..." >> /root/checkload.log
        systemctl start $SERVICE_NAME 2>/dev/null || service $SERVICE_NAME start
        sleep $CHECK_INTERVAL
        echo "$DATE_STR [GUARD] $SERVICE_NAME started (pid count: $(pgrep -c $SERVICE_NAME))" >> /root/checkload.log
    fi
fi

部署步驟

  1. 儲存腳本:`vim /root/checkload.sh` → 貼上內容 → `:wq`
  2. 賦予執行權限:`chmod 700 /root/checkload.sh`
  3. 安裝 `bc` (浮點比較需用):`yum install -y bc` / `apt-get install -y bc`
  4. 編輯 crontab:`crontab -e` → 新增 `*/2 * * * * /root/checkload.sh >> /root/checkload.log 2>&1`
  5. 驗證:`tail -f /root/checkload.log` 觀察執行紀錄

關鍵參數調校建議

場景MAX_LOAD 建議值說明
單核 VPS (1 vCPU)3.0 – 4.0負載 1.0 = 滿載,預留緩衝
雙核 VPS (2 vCPU)5.0 – 6.0負載 2.0 = 滿載
四核 VPS (4 vCPU)10.0 – 12.0負載 4.0 = 滿載
Nginx + PHP-FPM分別監控 nginx/master、php-fpm pool建議拆分兩個腳本,針對性重啟

進階擴展:整合監控與告警

  • **Prometheus + Node Exporter**:`node_load1` / `node_load5` / `node_load15` 圖表化
  • **Grafana 告警**:負載持續 > 閾值 5 分鐘 → Telegram/Email/钉钉通知
  • **自動擴容**:結合雲端 API (AWS ASG / 阿里雲伸縮組) 觸發擴容而非單純重啟
  • **攻擊特徵識別**:腳本中加入 `netstat -antp | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -5` 記錄攻擊源 IP

結語

「負載過高自動重啟 Web 服務」是**治標不治本**的應急手段,但對資源受限的 VPS 而言,往往是**成本最低、部署最快、見效最直接**的保命稻草。生產環境務必疊加:雲端防護 → 邊界限流 → 應用層快取/降級 → 主機端守護腳本 → 監控告警 → 自動擴容,構建完整彈性防禦體系。

Copyright © Windows教程網 All Rights Reserved