告警为什么会抖动、重复、刷屏?for 和 keep_firing_for 各解决什么?分组、repeat_interval、抑制、静默怎么减少噪音?这篇用 Prometheus 3.15.0 告警规则和 Alertmanager 0.34.1 逐项量出来。
规则 | firing 通知次数 | firing 通知时刻(s) | resolved 通知次数 | resolved 通知时刻(s)
-------------------------------+-------------+----------------+---------------+-----------------
for: 0s | 2 | 38, 54 | 2 | 44, 78
for: 5s | 1 | 59 | 1 | 77
for: 15s | 1 | 69 | 1 | 81
for: 0s + keep_firing_for: 10s | 4 | 14, 44, 54, 84 | 2 | 50, 90
FlapFor0 的 webhook 通知明细(通知时刻 | 整条通知的状态 | 其中该告警的状态、startsAt、endsAt,时间都相对时间线起点):
38.0 s | firing | firing start 35.0 end nan
44.0 s | resolved | resolved start 35.0 end 38.0
54.0 s | firing | firing start 51.0 end nan
78.0 s | resolved | resolved start 51.0 end 76.0
FlapKeep10 的 webhook 通知明细(通知时刻 | 整条通知的状态 | 其中该告警的状态、startsAt、endsAt,时间都相对时间线起点):
14.0 s | firing | firing start 11.0 end nan
44.1 s | firing | firing start 11.0 end nan
50.1 s | resolved | resolved start 11.0 end 48.0
54.0 s | firing | firing start 51.0 end nan
84.0 s | firing | firing start 51.0 end nan
90.0 s | resolved | resolved start 51.0 end 86.0
for: 5s 和 for: 15s 要求条件连续成立这么久才从 pending 变 firing,3 秒的短暂异常到不了,只有持续异常才通知(通知时刻比异常开始晚 for 的时长再加 group_wait 3 s 和评估的延迟)。for: 0s 时,短暂异常有没有通知取决于它和 Alertmanager 分组计时(group_wait、group_interval)的相位:一个告警要在计时点到来时还处于 firing 才会发出 firing 通知,在计时点之前已经恢复的,Alertmanager 什么都不发——看上面 FlapFor0 的明细,三次短暂异常里发出通知的只有 startsAt 对应的那一次(具体是哪几次每次运行会不同)。keep_firing_for 在条件不再成立之后继续保持 firing 一段时间:FlapKeep10 的 startsAt 到 endsAt 是一整段,相隔 9 s 的三次短暂异常被合并成了一个告警,只发一次 firing 和一次 resolved;持续异常那次 firing 之后还有第二次 firing 通知,那是 repeat_interval 到期后的重复通知for 过滤掉短暂异常,keep_firing_for 把相隔不远的几次合成一个告警;for: 0s 时短暂异常是否通知取决于计时相位。
分组方式 | 第 100 到 125 秒 firing 通知的次数 | 通知里的告警总数 | 每次通知里的告警数(前几次) ----------------------------+----------------------------+----------+------------------ group_by: [alertname] | 1 | 20 | 20 group_by: [alertname, inst] | 20 | 20 | 1, 1, 1, 1, 1, 1… 按 alertname 分组时,20 个同样的告警合并成一条通知;按 alertname + inst 分组,每个实例一条通知,同一时间会来 20 条
group_by 决定一条通知里合并哪些告警,把 20 个实例的同类告警合成一条。
ClusterDown 的 firing 通知时刻(s):[104.1, 140.4];resolved 通知时刻(s):[152.1]。第一次通知在告警开始之后 4.1 s(group_wait 加上规则评估),第二次通知比第一次晚 36.3 s:repeat_interval 是 30 s,实际的间隔落在 group_interval(6 s)的计时点上,所以是 30 s 到 36 s 之间,直到恢复才发 resolved
持续的告警按 repeat_interval 重复通知,实际间隔落在 group_interval 的计时点上。
告警 | firing 通知次数 | Alertmanager API 中的状态(ClusterDown 和 InstanceDown 取第 120 秒,Silenced 取第 70 秒)
--------------------------+-------------+------------------------------------------------------------------------------------------------------------------
ClusterDown(critical) | 2 | {'inhibitedBy': [], 'mutedBy': [], 'silencedBy': [], 'state': 'active'}
InstanceDown(warning,被抑制) | 0 | {"inhibitedBy": ["e38c8bef90d27264"], "mutedBy": [], "silencedBy": [], "state": "suppressed"}
Silenced(有静默,第 70 秒的快照) | 0 | {"inhibitedBy": [], "mutedBy": [], "silencedBy": ["4d5ceda6-81d6-4e58-8e59-5fecc25394c8"], "state": "suppressed"}
被抑制或被静默的告警仍然存在于 Alertmanager 里(状态是 suppressed),只是不发通知;去掉 critical 告警或者静默到期之后,它们才会通知
ERRORS {}被抑制或静默的告警仍然在 Alertmanager 里,只是不发通知。