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

187 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [microservice, alerting, slo, error-budget, on-call]
create time: 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%,否则赔偿 |
```mermaid
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 小时(几乎无意义)
```
### 基于错误预算的告警策略
```mermaid
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. 分级设计
```mermaid
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
事故复盘不问"谁干的",问"流程哪里可以改进":
```mermaid
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 项 ✅ —— 你的告警需要认真治理了。
## 关联笔记
- [[04-可观测性/01-Metrics监控]] — Metrics 是告警的数据来源
- [[05-部署运维/04-SRE实践]] — SLO/Error Budget 的详细方法论
- [[02-服务治理/06-容错模式]] — 熔断器状态可以作为告警信号