生產環境 MongoDB 偶發連接數飆升導致服務不可用,編寫一個定時腳本監控並自動重啟,過程中踩中 Heredoc 命令替換、crontab 環境變量、進程誤殺三大坑,記錄避坑指南。
mongo --quiet 執行 db.serverStatus().connections 獲取當前連接數。current 字段。current > 5800(預留 200 緩衝,maxConns=6000)。numactl --interleave=all 啟動新實例。#!/bin/bash
# source /etc/profile # 若 crontab 環境變量缺失可取消註釋
# 1. 獲取連接數:Heredoc 必須獨佔一行,結束標譤 EOF 後另起一行放反引號或 $()
conn=$( /usr/bin/mongo --quiet <<'EOF'
db.serverStatus().connections
exit
EOF
)
# 2. 解析 JSON:current: 123 格式
curr=$(echo "$conn" | grep -o 'current: [0-9]*' | awk '{print $2}')
echo "[$(date)] Current connections: $curr"
if [ "$curr" -le 5800 ]; then
echo "OK"
else
echo "连接数超限,准备重启..."
# 3. 精準查找進程:用 maxConns 參數過濾,避免殺掉 crontab 子進程自身
pids=$(ps -ef | grep "maxConns" | grep -v grep | awk '{print $2}')
for pid in $pids; do
echo "Killing $pid"
kill -9 "$pid"
done
echo "进程已杀掉"
# 4. 後台啟動,輸出重定向到 /dev/null
nohup numactl --interleave=all /usr/local/mongodb/bin/mongod \
--dbpath=/home/mongo/mongodb/data/ \
--logpath=/home/mongo/mongodb/logs/mongodb.log \
--maxConns=6000 --logappend >/dev/null 2>&1 &
echo "重启完成"
fi
| 坑點 | 現象 | 根因 | 修正 |
|---|---|---|---|
| Heredoc 命令替換語法錯誤 | syntax error near unexpected token |
反引號 ` 或 $() 必須放在 結束 EOF 之後另起一行,不能跟在同一行 |
結束 EOF 後換行再寫 ) 或 ` |
| crontab 執行不生效 | 手動運行正常,定時任務卡在 "准备重启" 日志無後續 | ps -ef | grep mongo 會匹配到 crontab 衍生的子 Shell 進程自身(命令行含 mongo 關鍵字),kill -9 導致腳本自殺,後續啟動命令不執行 |
改用 grep "maxConns" 精準匹配 mongod 進程參數 |
| 環境變量缺失 | mongo: command not found |
crontab 不加載用戶 .bash_profile |
腳本開頭 source /etc/profile 或使用絕對路徑 /usr/bin/mongo |
flock)防止並發執行。