现场是这样的。Prometheus 2.45 配了 rule_files,group 的 interval 和全局 evaluation_interval 都是 1m,节点掉线后告警过了两分四十秒才发出来,值班同事以为是监控没配。
中间走过弯路,把「抓取间隔是 30s,指标本身就带一次抓取滞后」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。group 的 interval 从整分钟对齐开始算,评估时刻和故障时刻错开;for 子句又叠加了一个持续时间,实际延迟是两者之和;Alertmanager 的 group_wait 默认 30s,通知又压了一轮。
动手时先看规则组的评估时间
curl -s 127.0.0.1:9090/api/v1/rules | jq '.data.groups[] | {name,interval,lastEvaluation}'
接着确认抓取间隔和 for 的配置
grep -n -E 'scrape_interval|evaluation_interval' /etc/prometheus/prometheus.yml && grep -n -A5 'alert:' /etc/prometheus/rules/*.yml
缩短评估间隔并去掉多余的 for
sed -i 's/^\s*evaluation_interval:.*/ evaluation_interval: 15s/' /etc/prometheus/prometheus.yml
等前面都确认过,再重载配置后复测一次
curl -X POST 127.0.0.1:9090/-/reload && sleep 60 && curl -s 127.0.0.1:9090/api/v1/alerts | jq '.data.alerts | length'
恢复的判定其实很直接。模拟节点失联,告警四十秒内进入 firing,Alertmanager 收到通知的时间与故障时间差在一分钟内。
补一句。评估间隔不是越短越好,规则多时会拖垮 Prometheus;for 用来抑制抖动,但对必须秒级发现的指标就该设成 0。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
