監控 100 臺服務器磁盤,內存,CPU利用率腳本
以下是一個優化后的監控腳本,用于同時監控100臺服務器的磁盤、內存和CPU利用率,并支持并發執行以提高效率:
#!/bin/bash
# 服務器監控腳本 - 支持并發獲取100臺服務器系統指標
# 功能:同時監控磁盤、內存、CPU利用率
# 需要提前配置SSH免密登錄和目標服務器IP列表# 配置參數
HOST_FILE="server_list.txt" # 服務器IP列表文件
MAX_CONCURRENCY=20 # 最大并發數(避免過高負載)
LOG_DIR="monitor_logs" # 日志存放目錄
CURRENT_DATE=$(date +%Y%m%d) # 當前日期# 創建日志目錄
mkdir -p "$LOG_DIR"
OUTPUT_FILE="$LOG_DIR/monitor_report_$CURRENT_DATE.csv"# 檢查服務器列表文件
if [[ ! -f "$HOST_FILE" ]]; thenecho "錯誤:服務器列表文件 $HOST_FILE 不存在!"exit 1
fi# 準備CSV文件表頭
echo "Hostname,IP,Timestamp,DisktUsed(%),MemoryUsed(%),CPULoad" > "$OUTPUT_FILE"# 并發執行控制變量
declare -A running_ssh # 跟蹤正在運行的SSH進程
declare -A host_outputs # 存儲主機輸出
running_count=0# 核心監控函數
monitor_server() {local ip="$1"{# 獲取主機名local hostname=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$ip" 'hostname' 2>/dev/null)if [[ -z "$hostname" ]]; thenecho "$ip,,連接失敗: $(date +%T),N/A,N/A,N/A"returnfi# 收集系統指標read -r timestamp disk_usage memory_usage cpu_load <<< $(ssh "$ip" \'ts=$(date +%T);disk=$(df -h / | awk "NR==2{print \$5}" | tr -d "%");mem=$(free | awk "/Mem/{printf \"%.0f\", (\$3-\$6-\$7)*100/\$2}"); # 計算真實內存使用cpu=$(top -bn1 | awk "/Cpu/ {printf \"%.1f\", 100 - \$8}"); # 獲取CPU利用率echo "$ts $disk $mem $cpu"')# 輸出CSV格式結果echo "$hostname,$ip,$timestamp,${disk_usage:-0},${memory_usage:-0},${cpu_load:-0}"} >> "$OUTPUT_FILE" 2>/dev/null
}# 主監控循環
while IFS= read -r ip; do# 跳過空行和注釋[[ -z "$ip" || "$ip" =~ ^# ]] && continue# 等待空閑槽位while (( running_count >= MAX_CONCURRENCY )); dosleep 0.2# 檢查已完成的進程for pid in "${!running_ssh[@]}"; doif ! kill -0 "$pid" 2>/dev/null; thenunset running_ssh["$pid"]((running_count--))fidonedone# 啟動監控任務monitor_server "$ip" &running_ssh[$!]="$ip"((running_count++))
done < "$HOST_FILE"# 等待所有后臺任務完成
wait
echo "監控完成! 結果已保存到: $OUTPUT_FILE"
腳本關鍵優化點與功能說明:
- 并發處理機制
while (( running_count >= MAX_CONCURRENCY )); dosleep 0.2for pid in "${!running_ssh[@]}"; doif ! kill -0 "$pid" 2>/dev/null; thenunset running_ssh["$pid"]((running_count--))fidone
done
- 使用進程池技術控制并發數量(默認20)
- 實時檢測進程狀態釋放槽位
- 避免同時發起過多SSH請求導致網絡擁堵
- 指標收集函數
read -r timestamp disk_usage memory_usage cpu_load <<< $(ssh "$ip" \'ts=$(date +%T);disk=$(df -h / | awk "NR==2{print \$5}" | tr -d "%");mem=$(free | awk "/Mem/{printf \"%.0f\", (\$3-\$6-\$7)*100/\$2}"); cpu=$(top -bn1 | awk "/Cpu/ {printf \"%.1f\", 100 - \$8}");echo "$ts $disk $mem $cpu"')
-
磁盤使用:監控根分區使用率(可修改為指定分區)
-
真實內存計算:
($3-$6-$7)/$2 * 100
計算公式
-
$3
:已用內存 -
$6
:緩存(cache) -
$7
:緩沖(buffer) -
CPU利用率:100% - 空閑時間 = 實際使用率
- 錯誤處理與超時
local hostname=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$ip" 'hostname' 2>/dev/null)
if [[ -z "$hostname" ]]; thenecho "$ip,,連接失敗: $(date +%T),N/A,N/A,N/A"return
fi
- SSH超時設置(5秒)
- 連接失敗自動記錄錯誤信息
- StrictHostKeyChecking跳過密鑰確認
- 日志與輸出
echo "Hostname,IP,Timestamp,DisktUsed(%),MemoryUsed(%),CPULoad" > "$OUTPUT_FILE"
- CSV格式輸出,兼容Excel分析
- 按日期生成日志文件(自動創建目錄)
- 表頭清晰標注指標單位
- 內存計算優化
mem=$(free | awk "/Mem/{printf \"%.0f\", (\$3-\$6-\$7)*100/\$2}")
- 創新點:計算真實使用內存 = 總內存 - (free + buffers + cache)
- 區別于簡單計算
used/total*100
,更準確反映應用實際內存占用
使用說明:
- 準備工作:
# 創建服務器列表文件
echo "192.168.1.101" >> server_list.txt
echo "192.168.1.102" >> server_list.txt
# ...添加100臺服務器IP# 配置SSH免密登錄
ssh-keygen
for ip in $(cat server_list.txt); do ssh-copy-id $ip
done# 添加執行權限
chmod +x server_monitor.sh
- 執行監控:
./server_monitor.sh
- 輸出示例:
Hostname,IP,Timestamp,DisktUsed(%),MemoryUsed(%),CPULoad
web-node1,192.168.1.101,14:35:22,35,68,24.5
db-master,192.168.1.102,14:35:23,12,45,8.3
...(100臺數據)
注意事項:
- 內存計算使用CentOS/RHEL的
free
命令輸出格式 top -bn1
需要服務器支持batch模式- 如需監控指定分區,修改df命令的掛載點
- 對于Ubuntu系統,調整內存計算公式(
free -m
輸出列不同) - 可添加閾值告警功能(在echo前添加判斷)
- 日志文件可配置定時清理(如保留7天數據)
此腳本優化了服務器監控的效率和準確性,特別是改進了內存使用率的計算方式,能更真實地反映服務器的內存壓力情況。