凌晨 Prometheus 告警风暴:我把 200 条冗余告警砍到 12 条,值班终于能睡整觉了

发布时间:2026/7/3 6:36:57

凌晨 Prometheus 告警风暴:我把 200 条冗余告警砍到 12 条,值班终于能睡整觉了 凌晨 Prometheus 告警风暴我把 200 条冗余告警砍到 12 条值班终于能睡整觉了上周三凌晨 2 点我被手机震醒。不是一条是连续几十条 Prometheus 告警。打开企业微信值班群里已经炸了——“磁盘使用率超过 80%”、“CPU 使用率过高”、“服务响应时间超过 500ms”相同的几条告警每隔 5 分钟重复一次像机关枪一样刷屏。那一晚我处理了 3 个小时最后发现真正需要人工介入的问题只有 2 个。剩下 198 条全是噪音。问题有多严重第二天我拉了一下数据结果触目惊心过去 7 天共产生告警1,847 条其中真正需要处理的23 条占比 1.2%重复告警同一问题在短时间内多次触发1,102 条已知的正常波动被误报612 条测试环境告警混到生产群110 条也就是说我们值班的人 98% 的时间都在处理假告警。长期下来团队形成了狼来了效应——看到告警先怀疑是不是误报而不是立刻响应。这很要命。万一哪天真的出了大事第一反应是又是误报吧那可能就凉透了。第一步给告警做体检我决定先不急着改规则而是搞清楚现状。写了个脚本把过去 30 天的告警全部导出来分析#!/bin/bash# 导出 Prometheus Alertmanager 历史告警# 需要 alertmanager 开启 --web.enable-lifecycle 和 API 访问ALERTMANAGER_URLhttp://alertmanager:9093OUTPUT_DIR/tmp/alert-analysismkdir-p$OUTPUT_DIR# 获取过去 30 天的告警curl-s${ALERTMANAGER_URL}/api/v2/alerts?silencedfalseinhibitedfalseactivetrue\|jq-r.[] | {startsAt, endsAt, labels: .labels.alertname, severity, instance}\$OUTPUT_DIR/alerts-raw.json# 统计每个告警名称的触发次数echo 告警触发频次 TOP 20 cat$OUTPUT_DIR/alerts-raw.json|jq-r.labels|sort|uniq-c|sort-rn|head-20# 统计重复告警相同 alertname instance1 小时内多次触发echo 高频重复告警 cat$OUTPUT_DIR/alerts-raw.json|jq-sgroup_by(.labels .instance) | map(select(length 5)) | .[] | {alert: .[0].labels, count: length}跑完脚本我发现几个典型问题1. 阈值设置过于敏感磁盘使用率告警阈值设的是 75%。但我们的日志轮转策略是 80% 触发清理也就是说 75%-80% 这个区间属于预期内的正常波动。这个区间里的告警过去 30 天触发了 400 多次。2. 缺少告警收敛一个节点宕机会同时触发NodeDownCPU 高内存高磁盘只读服务不可用接口超时6 条告警指向同一个根因。但 Alertmanager 没有配置抑制规则inhibition导致全部发到值班群。3. 测试环境告警未隔离测试环境的 Prometheus 和生产的 Alertmanager 接在了一起。测试同学跑压测的时候我们的值班群跟着一起爆炸。第二步动手术找到病根开始逐一处理。调整阈值区分告警和通知我把阈值逻辑重新梳理了一遍# 优化前的规则过于敏感-alert:DiskUsageHighexpr:(node_filesystem_size_bytes-node_filesystem_avail_bytes) / node_filesystem_size_bytes * 10075for:1mlabels:severity:warning# 优化后的规则-alert:DiskUsageCriticalexpr:(node_filesystem_size_bytes-node_filesystem_avail_bytes) / node_filesystem_size_bytes * 10085for:5mlabels:severity:criticalannotations:summary:磁盘使用率超过 85%需要人工处理-alert:DiskUsageWarningexpr:(node_filesystem_size_bytes-node_filesystem_avail_bytes) / node_filesystem_size_bytes * 10075for:30mlabels:severity:infoannotations:summary:磁盘使用率超过 75%请关注核心改动75% 改为 info 级别持续 30 分钟才发且不发值班群只记日志85% 才是 critical持续 5 分钟发值班群给每个告警加明确的summary说明需要做什么配置告警抑制避免轰炸在 Alertmanager 里加了抑制规则inhibit_rules:# 节点宕机时抑制该节点上的其他资源类告警-source_matchers:-alertname NodeDowntarget_matchers:-severity ~ warning|criticalequal:-instance# 服务不可用时抑制该服务的接口超时告警-source_matchers:-alertname ServiceDowntarget_matchers:-alertname ~ ApiTimeout|ErrorRateHighequal:-service效果立竿见影。测试了一下模拟节点宕机原来 6 条告警变成 1 条。路由分流测试环境别来添乱route:group_by:[alertname,cluster,service]group_wait:30sgroup_interval:5mrepeat_interval:12hreceiver:defaultroutes:# 测试环境告警发到测试群-match:env:testingreceiver:testing-alertsgroup_interval:30mrepeat_interval:24h# info 级别不发值班群只记日志-match:severity:inforeceiver:null# critical 立即电话通知-match:severity:criticalreceiver:pagerduty-criticalgroup_wait:10srepeat_interval:30mreceivers:-name:null-name:defaultwebhook_configs:-url:http://wecom-webhook:8080/send-name:testing-alertswebhook_configs:-url:http://wecom-webhook:8080/send-testing-name:pagerduty-criticalpagerduty_configs:-service_key:secret清理僵尸告警规则有些告警规则是半年前加的业务早就下线了规则还在。我挨个检查# 找出 30 天内从未触发的告警规则# 用 promtool 检查规则有效性promtool check rules /etc/prometheus/rules/*.yml# 对比告警规则列表和实际触发记录# 未触发的规则标记为待 review删掉了 17 条历史遗留规则大部分是旧业务的自定义 exporter 产生的。第三步建个看板持续盯治理完不是结束得防止反弹。我在 Grafana 搭了个告警质量看板核心指标# 告警信噪比真正需要处理的 / 总告警数 (sum(rate(alertmanager_alerts{severity~critical|warning}[1d])) - sum(rate(alertmanager_alerts{severityinfo}[1d]))) / sum(rate(alertmanager_alerts[1d])) # 重复告警比例 sum(rate(alertmanager_alerts[1d])) / count(count by(alertname, instance) (alertmanager_alerts)) # 平均告警恢复时间 histogram_quantile(0.95, sum(rate(alertmanager_alert_duration_seconds_bucket[1d])) by (le))设了每周一次的 review 会议超过 10 条重复告警的规则必须分析原因。踩坑记录坑 1Alertmanager 的forduration 和group_interval搞混了for是 Prometheus 里告警持续多久才变成 firing 状态。group_interval是 Alertmanager 里同一组告警多久发一次通知。我之前以为把for设长就能减少通知其实不对。for设太长会延迟真实告警的发现时间。正确做法是for保持合理1-5 分钟用group_interval和repeat_interval控制通知频率。坑 2抑制规则配反了第一次写 inhibit_rules 的时候把 source 和 target 写反了。结果 NodeDown 没抑制其他告警反而其他告警抑制了 NodeDown。敲黑板source 是根因告警target 是被抑制的告警。坑 3info 级别的告警堆积在 Alertmanager UIinfo 级别虽然不发通知但 Alertmanager 里还是能看到。几千条 info 告警把 UI 卡得巨慢。解决给 info 告警单独配一个短的group_interval30m并且加一条路由直接丢到nullreceiver不进入 Alertmanager 的活跃告警列表。坑 4测试环境压测把磁盘打满触发 critical 告警测试环境的磁盘阈值和生产的用的一套规则。压测时日志暴涨磁盘告警级别是 critical直接电话打给值班。解决按环境维度拆分规则文件prod-rules.yml和testing-rules.yml测试环境的阈值放宽且严重级别最高到 warning。写在最后治理完后我们的告警从 200 条砍到 12 条信噪比从 1.2% 提升到 67%。值班的人终于不用每隔几分钟看一次手机了。但告警治理不是一次性任务。业务在变规则会老化新的误报会不断冒出来。我现在每周花 10 分钟扫一眼告警质量看板有问题立刻修不让它积累成风暴。如果你也在被告警轰炸别急着加人值班。先拉个数据看看说不定 90% 的告警根本不该存在。有问题欢迎评论区交流。

相关新闻