答案是:用Shell脚本控制iostat采样节奏、过滤设备、聚合关键指标并检测波动,生成可读报告。脚本支持自定义设备与持续时间,输出%util、IOPS、吞吐量、await等统计及波动事件,无需额外依赖,适用于部署监控场景。

在部署期间实时监控磁盘 I/O 负载,关键不是“一直跑 iostat”,而是用 Shell 脚本控制采样节奏、聚合数据、识别波动特征,并输出可读报告。下面是一套轻量、可靠、无需额外依赖的实现方式。
一、明确监控目标和采样策略
iostat 默认输出是瞬时快照,直接重定向会混杂设备名、标题行和多轮数据,不利于分析。需做到:
- 固定采样间隔(如每 2 秒一次),持续采集 5–10 分钟(覆盖典型部署窗口)
- 只抓关键指标:%util(设备忙时百分比)、r/s + w/s(IOPS)、rkB/s + wkB/s(吞吐量)、await(平均等待毫秒)
- 过滤掉 loop、zram 等非物理设备,聚焦 sda/nvme0n1 等主磁盘
- 自动记录部署开始/结束时间戳,便于对齐操作日志
二、编写核心监控脚本(含波动检测)
保存为 disk-monitor.sh,赋予执行权限:chmod +x disk-monitor.sh
#!/bin/bash
DEVICE="${1:-sda}" # 可传入设备名,如 nvme0n1;默认 sda
DURATION=${2:-300} # 总监控时长(秒),默认 5 分钟
INTERVAL=2 # 每次采样间隔(秒)
LOGFILE="iostat_$(date +%s).log"
REPORT="report_$(date +%s).txt"
<p>echo "▶ 开始监控 $DEVICE,持续 $DURATION 秒($INTERVAL 秒/次)..." | tee "$REPORT"
echo "部署开始时间: $(date)" | tee -a "$REPORT"
echo "日志文件: $LOGFILE" | tee -a "$REPORT"</p><h1>仅输出 CSV 格式数据(无标题、无空行),便于后续处理</h1><p>iostat -dx $INTERVAL $((DURATION/INTERVAL)) | \
awk -v dev="$DEVICE" '
$1 == dev {
printf "%s,%s,%s,%s,%s,%s\n",
strftime("%H:%M:%S"), $2, $3, $4, $10, $14
}
' > "$LOGFILE"</p><p>echo -e "\n▶ 数据采集完成,生成分析报告..." | tee -a "$REPORT"</p><h1>计算基础统计(最大 %util、平均 await、IOPS 峰值等)</h1><p>if [ -s "$LOGFILE" ]; then
UTIL_MAX=$(awk -F, '{print $6}' "$LOGFILE" | sort -nr | head -1 | cut -d. -f1)
AWAIT_AVG=$(awk -F, '{sum+=$5; cnt++} END {printf "%.1f", sum/cnt}' "$LOGFILE")
IOPS_PEAK=$(awk -F, '{$3+$4 > max {max = $3+$4}} END {print int(max)}' "$LOGFILE")</p><p>echo -e "\n? 关键指标摘要:" | tee -a "$REPORT"
echo " • 最高磁盘利用率: ${UTIL_MAX:-0}%(临界阈值建议 ≤85%)" | tee -a "$REPORT"
echo " • 平均 I/O 等待时间: ${AWAIT_AVG:-0} ms(>15ms 表示存在延迟压力)" | tee -a "$REPORT"
echo " • 峰值 IOPS: ${IOPS_PEAK:-0} ops/s" | tee -a "$REPORT"</p><h1>检测明显波动:连续 3 次 %util > 70%,且比前 3 次均值高 2 倍 → 视为“部署写入爆发”</h1><p>FLUCTUATION=$(awk -F, -v thresh=70 '
{ util[NR] = $6; time[NR] = $1 }
NR > 3 {
prev_avg = (util[NR-3]+util[NR-2]+util[NR-1])/3
if (util[NR] > thresh && util[NR] > prev_avg*2) {
print "⚠ 在 " time[NR] " 发现 I/O 波动:util=" util[NR] "%(前3次均值=" prev_avg ")"; exit
}
}
' "$LOGFILE")</p><p>if [ -n "$FLUCTUATION" ]; then
echo -e "\n? 波动事件:" | tee -a "$REPORT"
echo " $FLUCTUATION" | tee -a "$REPORT"
else
echo -e "\n✅ 未检测到显著 I/O 波动(基于连续阈值触发规则)" | tee -a "$REPORT"
fi</p><p>echo -e "\n? 原始采样数据(时间, r/s, w/s, rkB/s, await, %util):" | tee -a "$REPORT"
head -5 "$LOGFILE" | sed 's/,/ /g' | awk '{printf " %s %s %s %s %s %s\n", $1,$2,$3,$4,$5,$6}' | tee -a "$REPORT"
echo " ...(共 $(wc -l < "$LOGFILE") 行,完整见 $LOGFILE)" | tee -a "$REPORT"
else
echo "❌ 未采集到有效数据,请检查设备名或 iostat 是否可用" | tee -a "$REPORT"
fi</p><p>echo -e "\n✅ 报告生成完毕:$REPORT" | tee -a "$REPORT"
三、部署时一键调用并关联上下文
不要脱离部署流程单独运行。推荐在部署脚本中嵌入:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 部署前启动监控(后台运行,记录 PID)
- 部署命令执行后,自动 kill 监控进程并生成报告
- 把报告路径写入部署日志,方便回溯
示例片段:
# 部署脚本 deploy.sh 中加入 ./disk-monitor.sh nvme0n1 600 & # 监控 10 分钟,后台运行 MONITOR_PID=$! <h1>执行实际部署(如 docker-compose up、ansible-playbook 等)</h1><p>ansible-playbook deploy.yml</p><p>kill $MONITOR_PID 2>/dev/null wait $MONITOR_PID 2>/dev/null</p><p>echo "? 部署完成,I/O 报告已生成,详见上一条输出" >> deploy.log
四、进阶建议(按需启用)
不强求一步到位,但可逐步增强:
- 绘图辅助:用 gnuplot 或 Python(pandas+matplotlib)读取 CSV 画 %util 时间曲线,一眼识别毛刺
-
阈值告警:若 %util 连续 5 次 >90%,发送邮件或写入 syslog(
logger -t disk-alert "High util on $DEVICE") -
多设备对比:修改脚本支持传入多个设备(
./disk-monitor.sh sda nvme0n1),分别统计并横向对比 -
与 top/ps 关联:在波动时刻用
pidstat -d 1 3快速定位高 I/O 进程
这套方法不依赖数据库或 Web 界面,纯 Shell + iostat,适合 CI/CD 环境、离线服务器或资源受限节点。重点在于用结构化采样替代人工观察,用简单规则替代复杂模型——真正解决“部署时磁盘是不是扛住了”这个具体问题。

















