Squid 作為高效能代理快取伺服器,長期運行可能因記憶體洩漏、檔案描述符耗盡導致服務凍結。本文提供一個輕量級 Shell 監控腳本,每 30 秒檢查 Squid 工作進程數 (預期 3 個:1 master + 2 worker) 並監控埠 80 併發連線數,異常時自動重啟並記錄時間戳日誌,適合納入 /etc/rc.local 或 systemd 服務實現守護進程化部署。
#!/bin/sh
# 檔案:/usr/local/bin/squid_monitor.sh
# 用途:監控 Squid 進程與高併發,異常自動重啟
# 部署:chmod +x /usr/local/bin/squid_monitor.sh
# 加入 /etc/rc.local 或建立 systemd service
LOG_FILE="/var/log/squid_monitor.log"
SQUID_INIT="/etc/init.d/squid" # CentOS 6
# SQUID_INIT="/usr/libexec/squid/squid" # CentOS 7 systemd 環境下改用 systemctl restart squid
# 確保日誌目錄存在
mkdir -p "$(dirname "$LOG_FILE")"
while true; do
sleep 30
# 1. 檢查 Squid 進程數 (預期 3: 1 master + 2 workers)
SQUID_NUM=$(ps -ef | grep -v grep | grep -c squid)
if [ "$SQUID_NUM" -ne 3 ]; then
$SQUID_INIT start
echo "$(date '+%Y-%m-%d %H:%M:%S') Squid process count=$SQUID_NUM, restarted!" >> "$LOG_FILE"
fi
# 2. 檢查埠 80 併發連線數 (超過 5000 視為異常)
HTTP_NUM=$(netstat -an | grep -c ':80 ')
if [ "$HTTP_NUM" -gt 5000 ]; then
$SQUID_INIT restart
echo "$(date '+%Y-%m-%d %H:%M:%S') HTTP connections=$HTTP_NUM > 5000, Squid restarted!" >> "$LOG_FILE"
fi
done
| 檢查項目 | 命令 | 正常基準 | 異常動作 |
|---|---|---|---|
| 進程存活 | ps -ef | grep squid | grep -v grep | wc -l | 3 個進程 | 啟動服務 |
| 高併發保護 | netstat -an | grep ':80 ' | wc -l | ≤ 5000 連線 | 重啟服務 (釋放資源) |
Squid 預設啟動 1 個 master 進程 (管理配置、日誌、信號) + squid.conf 中 workers 2 (或預設 CPU 核心數) 個 worker 進程處理實際請求。若 workers N 則預期進程數 = N+1。
cat > /etc/systemd/system/squid-monitor.service <<'EOF'
[Unit]
Description=Squid Monitor Daemon
After=network.target squid.service
Requires=squid.service
[Service]
Type=simple
ExecStart=/usr/local/bin/squid_monitor.sh
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=squid-monitor
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now squid-monitor
腳本中將 $SQUID_INIT restart 改為 systemctl restart squid。
cat > /etc/logrotate.d/squid-monitor <<'EOF'
/var/log/squid_monitor.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 root root
}
EOF
cooldown 機制:重啟後睡眠 120 秒再繼續檢查flock 防止多實例並行
# 腳本開頭加入
exec 200>/var/lock/squid_monitor.lock
flock -n 200 || exit 1
ps -o rss= -p $(pgrep -f 'squid.*worker') | awk '{sum+=$1} END {print sum/1024 " MB"}'lsof -p $(pgrep squid) | wc -l 對比 ulimit -nsquidclient -h localhost -p 3128 mgr:info 輸出pidstat -p $(pgrep squid) 1 1| 現象 | 原因 | 解決 |
|---|---|---|
| 腳本啟動後立即退出 | shebang 錯誤、權限不足、flock 鎖衝突 | chmod +x; 檢查 #!/bin/sh; 確保單實例 |
| 頻繁誤判重啟 | 檢查間隔太短、基準值不合理 | 調整 sleep 60、依實際流量調整閾值 |
| systemd 服務無法啟動 | Type=simple 但腳本為 daemon 化 | 腳本前景運行 (while true; do ... done),不要 fork |