磁盘io延迟告警需监控await、avgqu-sz等真实指标而非仅%iowait,采用连续3次await>80ms触发钉钉webhook告警,并通过while循环脚本守护运行。

当磁盘IO等待时间(如 iowait 或 I/O响应延迟)持续偏高,往往预示着存储瓶颈、慢盘、RAID降级或应用写入风暴,可能引发服务超时甚至宕机。单纯看CPU的 %iowait 不够精准——它反映的是CPU空闲时等待IO的时间比例,而真正关键的是块设备的实际响应延迟(如 `await`、`r_await`、`w_await`),尤其是 `iostat -x 1` 中的 `avgqu-sz`(平均队列长度)和 `await`(平均IO响应毫秒数)。下面给出一个轻量、可靠、可直接落地的Shell监控方案。
获取真实IO延迟指标:用 iostat 抓取关键字段
Linux自带的 iostat(来自 sysstat 包)是最佳选择。重点监控:
- await:单次IO平均耗时(ms),>50ms 值得警惕,>100ms 通常已影响业务
- avgqu-sz:平均IO请求队列长度,>2 表示设备持续积压
- %util:设备忙时占比,接近100%说明IO饱和(但SSD/NVMe下该值参考性下降,需结合 await)
推荐命令:iostat -dx 1 3 | awk '/^sd|nvme/ {print $1, $10, $11, $12, $14}' | tail -1 —— 每秒采样3次,取最后一次,过滤出物理盘(如 sda/nvme0n1),输出设备名、r_await、w_await、await、%util。
设定合理阈值并触发告警条件
避免误报,不只看单次峰值。建议采用“连续N次超标”策略(例如连续3次 await > 80ms):
- 定义变量:
THRESHOLD_AWAIT=80、THRESHOLD_QUEUE=2.5、ALERT_COUNT=3 - 每次采集后判断是否超标,达标则计数器+1;未达标则重置计数器
- 计数器达到
ALERT_COUNT时,记录时间戳并调用钉钉Webhook
用 curl 发送钉钉 Webhook(支持Markdown+@人)
钉钉机器人需在群设置中开启“自定义机器人”,获取 Webhook URL,并勾选“加签”(更安全)或使用“IP白名单”(简单场景)。发送示例:
curl -s -X POST "$WEBHOOK_URL"
-H 'Content-Type: application/json'
-d "{
"msgtype": "markdown",
"markdown": {
"title": "⚠️ 磁盘IO延迟告警",
"text": "## ⚠️ 磁盘IO延迟告警\n\n- **设备**: $DEV\n- **await**: ${AWAIT}ms(阈值${THRESHOLD_AWAIT}ms)\n- **avgqu-sz**: ${QUEUE}(阈值${THRESHOLD_QUEUE})\n- **时间**: $(date +'%F %T')\n- **主机**: $(hostname)\n\n> 建议立即检查:IO负载来源、磁盘健康(smartctl)、RAID状态、数据库慢查询或日志刷盘频率。"
},
"at": {
"atMobiles": ["138****1234"],
"isAtAll": false
}
}"
注意:atMobiles 填手机号(需在钉钉群内实名),isAtAll 设为 false 避免骚扰;若需@所有人,改为 true 并删除 atMobiles 字段。
守护运行:用 while true + sleep 封装成常驻脚本
将采集、判断、告警逻辑封装为循环脚本,加入系统开机自启(如 systemd service 或 crontab @reboot):
- 每10秒执行一次检测(太频繁加重负载,太长易漏告)
- 用临时文件(如
/tmp/io_alert_count)持久化计数器,防止脚本重启丢失状态 - 加入日志记录:
echo "$(date): $DEV await=$AWAIT alert_count=$count" >> /var/log/io_monitor.log - 异常时自动退出并邮件通知运维(可选增强)
不复杂但容易忽略:务必测试 Webhook 是否能真正收到消息,且确认钉钉机器人权限正常;首次部署建议先设宽松阈值(如 await > 200ms)观察基线,再逐步收紧。











