监控 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" ]]; then
echo "错误:服务器列表文件 $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" ]]; then
echo "$ip,,连接失败: $(date +%T),N/A,N/A,N/A"
return
fi
# 收集系统指标
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 )); do
sleep 0.2
# 检查已完成的进程
for pid in "${!running_ssh[@]}"; do
if ! kill -0 "$pid" 2>/dev/null; then
unset running_ssh["$pid"]
((running_count--))
fi
done
done
# 启动监控任务
monitor_server "$ip" &
running_ssh[$!]="$ip"
((running_count++))
done < "$HOST_FILE"
# 等待所有后台任务完成
wait
echo "监控完成! 结果已保存到: $OUTPUT_FILE"
脚本关键优化点与功能说明:
- 并发处理机制
while (( running_count >= MAX_CONCURRENCY )); do
sleep 0.2
for pid in "${!running_ssh[@]}"; do
if ! kill -0 "$pid" 2>/dev/null; then
unset running_ssh["$pid"]
((running_count--))
fi
done
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" ]]; then
echo "$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天数据)
此脚本优化了服务器监控的效率和准确性,特别是改进了内存使用率的计算方式,能更真实地反映服务器的内存压力情况。