Files
cs-note/hhs/MS/04-可观测性/04-告警管理.md
T
2026-05-24 11:42:38 +08:00

6.4 KiB
Raw Blame History

tags, create time
tags create time
microservice
alerting
slo
error-budget
on-call
2026-05-05

告警管理

概述

收集了这么多 Metrics、Logs 和 Traces,下一步是用数据驱动决策。告警系统是在问题影响用户之前及时响应的最后一道防线。

[!warning] 核心挑战:告警疲劳

如果一个团队每天收到 200 条告警,其中 195 条是误报或无需处理,工程师会对剩下的 5 条真正重要的告警产生"脱敏"。这就是 告警疲劳 (Alert Fatigue)。

SLO / Error Budget 告警

SLI / SLO / SLA 三层模型

层级 全称 含义 示例
SLI Service Level Indicator 实际测量的指标 P99 延迟 = 120ms
SLO Service Level Objective 内部目标值 P99 延迟 < 200ms(99.9%)
SLA Service Level Agreement 对外契约承诺 可用性 ≥ 99.95%,否则赔偿
flowchart LR
    Real["真实用户请求"] --> SLI{成功率达标?}
    SLI -- 是 --> SLO_OK["✅ SLO 达成"]
    SLI -- 否 --> BUDGET["消耗错误预算"]
    
    BUDGET --> Left{"预算 > 0?"}
    Left -- 是 --> Continue["继续发布新功能 🚀"]
    Left -- 否 --> Freeze["冻结发布 ❄️<br/>专注稳定性修复"]
    
    style SLO_OK fill:#e8f5e9
    style Freeze fill:#ffebee

错误预算计算

每月允许停机时间 = 月总分钟数 × (1 - SLO)

SLO = 99.9% → 30×24×60×0.1% = 43.2 分钟
SLO = 99.95% → 30×24×60×0.05% = 21.6 分钟
SLO = 99.99% → 30×24×60×0.01% = 4.3 分钟
SLO = 99% → 30×24×60×1%     = 432 分钟 ≈ 7.2 小时(几乎无意义)

基于错误预算的告警策略

flowchart TD
    BudgetLeft{"错误预算剩余"}
    
    BudgetLeft -- "> 50%" --> Aggressive["激进策略:<br/>保持常规告警阈值<br/>加快迭代节奏"]
    BudgetLeft -- "10~50%" --> Moderate["保守策略:<br/>降低告警阈值<br/>收紧发布频率"]
    BudgetLeft -- "< 10%" --> Emergency["紧急策略:<br/>所有非紧急告警暂停<br/>全员关注稳定性"]
    
    style Aggressive fill:#e8f5e9
    style Moderate fill:#fff3e0
    style Emergency fill:#ffebee

告警设计原则

1. 告警必须 Actionable

收到告警后知道该做什么,否则不要告。

每条告警规则都应该能回答以下问题:

# 问题 示例答案
1 什么问题? 支付服务 P99 延迟 > 2s 持续 5 分钟
2 谁负责? 支付组 On-Call: @zhangsan
3 怎么修复? 链接到 Runbook 📖 Runbook: 支付超时排查指南
4 多久升级? P1 无人响应 → 5min 后升级至组长

2. 分级设计

flowchart TD
    subgraph L1["P0 — 立即响应(电话 + IM)"]
        A1["HTTP 5xx 错误率 > 1% 持续 2min"]
        A2["核心接口 P99 > 2s 持续 5min"]
        A3["数据库连接池耗尽"]
    end
    
    subgraph L2["P1 — 当天处理(IM 通知)"]
        B1["单个服务错误率 > 5%"]
        B2["下游依赖超时率升高"]
        B3["磁盘使用 > 75%"]
    end
    
    subgraph L3["P2 — 本周修复(日报汇总)"]
        C1["CPU 使用率 > 80% 持续 1h"]
        C2["内存使用 > 85% 持续 1h"]
        C3["非核心服务 P99 异常"]
    end
    
    L1 --> ONCALL[On-Call 值班群]
    L2 --> OPS[运维监控群]
    L3 --> DAILY["每日健康报告"]
    
    style L1 fill:#ffebee
    style L2 fill:#fff3e0
    style L3 fill:#e3f2fd

3. 降噪与抑制

同一个根因可能触发连锁告警,需要抑制机制:

┌──────────┐    ┌──────────┐    ┌──────────┐
│ DB 宕机   │───→│ 服务 A 报错│───→│ 关联告警   │
└──────────┘    └──────────┘    │ 只发 Root Cause│
                                │ 其他静默       │
                                └──────────┘
技术 说明
告警分组 同一根因的多个告警合并为一条
静默期 Pod 重启后 5 分钟内不重复告警
维护窗口 已知变更期间暂时抑制非关键告警
继承抑制 DB 挂了 → 自动抑制依赖 DB 的所有服务的告警

On-Call 最佳实践

Runbook:告警处置手册

[!summary] Runbook 模板

字段 内容
标题 支付服务 P99 延迟 > 2s 持续 5 分钟
影响范围 下单接口超时,用户体验受损
检查步骤 ① 看 Grafana 延迟面板确认峰值时间点 → ② 查同期部署记录 → ③ 检查下游 DB 慢查询
常见原因 ① 新代码性能 regression → ② DB 连接池耗尽 → ③ 下游超时风暴
快速恢复 ① 回滚最近一次发布 → ② 扩容实例 → ③ 开启熔断降负载
彻底解决 排查根本原因,补充回归测试,完善容量规划

Blameless Postmortem

事故复盘不问"谁干的",问"流程哪里可以改进":

flowchart LR
    Incident["事故发生"] --> Contain["控制影响面"]
    Contain --> Investigate["调查根因"]
    Investigate --> Action["制定改进行动"]
    Action --> Share["分享经验教训"]
    
    style Incident fill:#ffebee
    style Contain fill:#fff3e0
    style Investigate fill:#e3f2fd
    style Action fill:#e8f5e9
    style Share fill:#f3e5f5

[!tip] 事后复盘三问

  1. 什么导致了这次事故? (技术根因)
  2. 为什么监控系统没有更早发现? (检测延迟)
  3. 下次如何避免同类问题? (流程改进)

告警疲劳自检清单

如果你的团队出现以下情况,说明告警体系需要重构:

  • On-Call 工程师下班前都要关闭/忽略一堆告警
  • 有人会在群里说 "这个告警不用管"
  • 同一个服务每天都触发相同的告警
  • 新同事不知道哪些告警是真的严重
  • PagerDuty/Oncall 通知已读率低于 50%

如果以上超过 2 项 ✅ —— 你的告警需要认真治理了。

关联笔记