要檢查伺服器連線是否緊繃

要檢查伺服器連線是否緊繃,可以從系統層級和 Apache 應用層級兩個維度來看。

使用 mod_status 監看即時看板

這是 Apache 內建最直觀的方法。它可以讓你看到每個 Worker 正在做什麼(讀取中、寫入中或閒置)。

  1. 啟用模組:Bash
    sudo a2enmod status
    sudo systemctl restart apache2
  2. 查看狀態:在伺服器本機輸入以下指令即可看到文字版的即時清單:Bash
    apache2ctl fullstatus
    你會看到一串符號,例如 _ 代表閒置,W 代表正在傳送資料,R 代表讀取請求。如果滿畫面都是 RW 且沒有 _,代表連線真的滿了。

使用系統指令檢查連線數

如果你想快速知道有多少連線正在排隊或連線中,可以使用以下指令:

1. 統計各狀態連線數

Bash

netstat -ant | awk '{print $6}' | sort | uniq -c | sort -n
  • ESTABLISHED:代表正在連線中的數量。
  • SYN_RECV:如果這個數字很高,可能正在遭受 SYN Flood 攻擊。
  • TIME_WAIT:代表連線已結束但在等待關閉,數字過高可能代表 KeepAliveTimeout 設定太長。

2. 統計特定連接埠(如 443)的連線 IP

這可以幫你抓出是哪些 IP 在瘋狂連線:

Bash

netstat -an | grep :443 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -n 10

觀察記憶體與 CPU (htop)

有時候連線數還沒滿,但 CPU 或記憶體已經先爆了。建議安裝並執行 htop

Bash

sudo apt install htop
htop

觀察 Load Average。如果數字長時間大於你的 CPU 核心數,代表系統處理不過來了。此外,看看 apache2 程式佔用的記憶體總量,如果 Swap 開始被大量使用,網站就會變得很慢。

總結緊繃的徵兆

  • apache2ctl fullstatus 顯示沒有閒置的 Worker。
  • 日誌持續出現 MaxRequestWorkers setting reached
  • netstat 顯示連線數接近你在 mpm_prefork.conf 設定的上限。

這是一個幫你整合好的簡單 Shell Script。你可以將它存成 check_server.sh,隨時用來檢查伺服器是否處於「緊繃」狀態。

建立檢查腳本

請執行以下指令建立檔案:

Bash

nano check_server.sh

貼入以下內容:

Bash

#!/bin/bash
echo "=== 1. Apache Worker Status (Scoreboard) ==="
# 這部分需要 mod_status 有開啟
apache2ctl status | grep "Scoreboard" || echo "mod_status not enabled"

echo -e "\n=== 2. Connection Counts by State ==="
netstat -ant | awk '{print $6}' | sort | uniq -c | sort -nr

echo -e "\n=== 3. Top 10 IP Connections (Port 80/443) ==="
netstat -an | grep -E ':80|:443' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -n 10

echo -e "\n=== 4. System Load and Memory ==="
uptime
free -h

賦予執行權限並執行:

Bash

chmod +x check_server.sh
./check_server.sh

如何解讀腳本結果

關於 Scoreboard (Worker 狀態)

你會看到一串符號,這對判斷連線壓力最有效:

  • _:代表 Waiting (閒置),越多代表伺服器越輕鬆。
  • R:代表 Reading (正在讀取請求),如果很多,可能是機器人正在慢速連線攻擊。
  • W:代表 Sending (正在傳送資料),代表正在處理正常業務。
  • .:代表 Open slot (尚未建立的進程),如果都是點,代表 Worker 數量還沒開到上限。

關於連線 IP 統計

如果前三名的 IP 連線數遠遠超過其他 IP(例如單一 IP 就有幾百個連線),那通常就是攻擊來源。配合你之前的日誌,如果這些 IP 都是來自 Cloudflare,請務必去 Cloudflare 面板開啟「Under Attack」模式或建立 WAF 規則。

關於記憶體 (free -h)

請特別注意 available 這一欄。如果 available 趨近於 0,或者 Swapused 正在上升,這代表 Apache 每個進程佔用的記憶體太大了,你可能需要減少 MaxRequestWorkers 的數量,以免系統因為記憶體不足而當機(OOM Killer)。


要把腳本裡的 netstat 換成 ss 其實很簡單,因為 ss 的輸出格式跟 netstat 非常接近,但執行速度更快。主要的差異在於 ss 預設會顯示欄位標題,而且處理欄位的方式略有不同。

更新後的腳本內容

以下是更換為 ss 之後的腳本版本:

Bash

#!/bin/bash
echo -e "\n=== 2. Connection Counts by State ==="
ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -nr

echo -e "\n=== 3. Top 10 IP Connections (Port 80/443) ==="
ss -an | grep -E ':80|:443' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -n 10

echo -e "\n=== 4. System Load and Memory ==="
uptime
free -h

修改重點說明

在連線狀態統計的部分,ss 的第一欄就是狀態,不像 netstat 是在第六欄,所以 awk 的參數改為 print $1。另外 ss 會輸出一行標題列,我加上了 NR>1 來跳過第一行,避免把 State 這個單字也算進統計結果裡。

在統計特定連接埠的部分,ss 的輸出格式中,遠端地址同樣位在第五欄,所以這部分與你原本的邏輯大致相同。不過要注意的是,如果你的環境使用 IPv6,地址格式可能會包含中括號,到時候可能需要針對 cut 的分隔符號做微調。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *