Skip to content

案例:故障 40 分钟才发现 ​

现象 ​

用户投诉后才有人知道服务挂了。事后查监控:

  • Grafana 面板上有红色曲线,但没有任何告警。
  • 告警群里有 3000 多条消息,全部被静音。
  • 值班同事说"昨天告警太多了,就关了通知"。

定位过程 ​

不是监控没数据,是告警体系失效。

第一步:盘点现有告警 ​

bash
curl -s http://prometheus:9090/api/v1/rules | jq '.data.groups[].rules[] | {name, severity: .labels.severity}' | head -20
json
{"name":"InstanceDown","severity":"critical"}
{"name":"HighCPU","severity":"warning"}
{"name":"HighCPU5m","severity":"warning"}
{"name":"CPU90","severity":"critical"}
...

同一个问题有 3 条规则,阈值分别是 80%、85%、90%。重复告警。

第二步:看告警量 ​

bash
curl -s http://alertmanager:9093/api/v2/alerts | jq 'length'
text
1842

1842 条活跃告警,其中大部分是同一个根因。

bash
curl -s http://alertmanager:9093/api/v2/alerts | jq -r '.[].labels.alertname' | sort | uniq -c | sort -rn | head
text
  420 HighCPU
  380 HighMemory
  312 DiskSpaceLow
  284 Http5xxHigh
  ...

第三步:确认关键告警是否在 ​

业务真的挂了,但 Http5xxHigh 的阈值是 5%,而故障期间错误率 100% —— 应该触发。查为什么没通知:

bash
curl -s http://alertmanager:9093/api/v2/status | jq '.config.route'
json
{
  "receiver": "dingtalk",
  "group_wait": "30s",
  "group_interval": "5m",
  "repeat_interval": "4h"
}

group_wait 30s、group_interval 5m 没问题。再看静默:

bash
curl -s http://alertmanager:9093/api/v2/silences | jq '.[] | {matchers, endsAt}'
json
{"matchers":[{"name":"alertname","value":"Http5xxHigh"}],"endsAt":"2026-11-30T00:00:00Z"}

有人把业务最关键的告警静默了一个月。

处置 ​

第一步:分类,砍掉噪音 ​

把指标分成三层:

层级内容通知方式
P0 紧急服务不可用、错误率飙升、数据丢失风险电话 + 群
P1 重要容量接近上限、主从延迟、磁盘 85%群
P2 提示CPU 高、连接数偏高、慢查询增多只看面板,不通知
text
P0 必须能在 5 分钟内响应
P1 当天处理
P2 每周复盘时看

第二步:从"指标告警"转向"症状告警" ​

CPU 80% 不一定是故障;用户下单失败一定是故障。

yaml
groups:
  - name: slo
    rules:
      # 关键:用户可见的症状
      - alert: ApiErrorRateHigh
        expr: |
          sum(rate(http_requests_total{job="order-api",status=~"5.."}[5m]))
          / sum(rate(http_requests_total{job="order-api"}[5m])) > 0.05
        for: 2m
        labels: { severity: critical }
        annotations:
          summary: "订单 API 5xx 比例 {{ $value | humanizePercentage }}"
          runbook: "https://wiki/runbook/order-api-5xx"

      - alert: ApiLatencyHigh
        expr: |
          histogram_quantile(0.99,
            sum(rate(http_request_duration_seconds_bucket{job="order-api"}[5m])) by (le)
          ) > 1.5
        for: 5m
        labels: { severity: warning }

      # 依赖
      - alert: RedisMasterDown
        expr: redis_up{job="redis"} == 0
        for: 1m
        labels: { severity: critical }

      - alert: KafkaConsumerLagHigh
        expr: sum by (consumergroup) (kafka_consumergroup_lag) > 100000
        for: 10m
        labels: { severity: warning }

for: 是关键:持续一段时间才触发,避免毛刺。

第三步:告警收敛 ​

yaml
# alertmanager.yml
route:
  receiver: default
  group_by: ['alertname', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - matchers: [severity="critical"]
      receiver: oncall-phone
      group_wait: 10s
      repeat_interval: 30m
    - matchers: [severity="warning"]
      receiver: dingtalk
    - matchers: [severity="info"]
      receiver: blackhole        # 不通知,只留面板

inhibit_rules:
  # 服务整体不可用时,抑制它下面的细分告警
  - source_matchers: [alertname="ServiceDown"]
    target_matchers: [severity=~"warning|info"]
    equal: ['service']
机制作用
group_by同一服务的多条告警合并成一条
group_wait等 30 秒,把相关告警攒一起发
repeat_interval4 小时内不重复打扰
inhibit_rules根因告警触发时,抑制派生告警

第四步:静默必须有期限和审批 ​

bash
# 只允许静默维护窗口,且必须填原因和时长
amtool silence add alertname="Http5xxHigh" \
  --duration=2h \
  --comment="发布 1.4.3,已知短时 5xx" \
  --author="zhangsan"

禁止"永久静默"。建议在 CI 里检查:任何 endsAt 超过 24 小时的静默都要告警。

第五步:值班与升级 ​

text
P0 触发 → 5 分钟未确认 → 升级到备份值班 → 15 分钟未确认 → 升级到负责人

没人在意的告警等于没有告警。

复盘 ​

问题根因改进
40 分钟才发现无告警加症状告警
3000 条/天重复规则 + 指标告警过多去重 + 分级
关键告警被静默静默无审批无期限强制时长 + 审计
面板有红但没人看只建面板不建告警面板只是辅助
值班同事关通知噪音太多先降噪再要求值守

告警的三个反模式

  1. 全量通知:所有告警都发群 → 很快没人看。
  2. 只看资源指标:CPU/内存告警一堆,用户可见的故障没告警。
  3. 无 Runbook:收到告警不知道做什么,只能等人。

每条 P0 告警都必须配一段"看到它先做什么"。

告警质量的自检问题

  • 这条告警响了,用户真的受影响吗?
  • 收到后我知道第一步做什么吗?
  • 过去一个月它响了几次?其中几次是真问题?

第三个问题答案是"很少"或"每次都是真问题",这条告警才有价值。否则合并、降级或删掉。

附:最小可用的告警清单 ​

如果从零开始,先上这六条:

告警条件
服务不可用健康检查连续 3 次失败
错误率高5xx 比例 > 5% 持续 2 分钟
延迟高P99 > 1.5s 持续 5 分钟
磁盘将满使用率 > 85%
依赖不可用Redis/MySQL/Kafka 连接失败
消费积压lag > 10 万持续 10 分钟

这六条能覆盖绝大多数"用户已经受影响"的场景。