12.2 告警与诊断界面:从信号到行动
告警系统的产物不是通知,而是及时、正确的人类行动。一个表达式即使数学正确,如果接收者不知道影响、紧迫度和下一步,它仍是失败的告警设计。
Page 由用户风险驱动
第 9 章已经用 burn rate 判断错误预算消耗。这里补上操作契约。每条会叫醒人的告警至少应满足:
- 正在发生或即将发生显著用户影响;
- 人现在采取行动能改善结果;
- 接收者明确且拥有处理权限;
- 注释中能定位 dashboard、runbook 和变更上下文;
- 数据缺失与正常值不会混淆。
CPU 80% 本身通常不满足这些条件。若 CPU 饱和会导致延迟 SLO 快速燃烧,page 用户影响,CPU 作为诊断信号;若只是长期容量趋势,创建工作时间 ticket。
for 延迟触发,keep_firing_for 缓冲恢复
下面假设 30 天请求型 SLO 为 99.9%,已按同一有效请求口径生成 1 小时和 5 分钟错误比例 recording rules,且两者保留相同的 service/故障域标签。0.0144 / 0.001 = 14.4 倍预算消耗率;流量近似稳定时,持续 1 小时约消耗完整窗口预算的 2%。这是一档快烧告警,其他较慢窗口仍需另设:
groups:
- name: atlas-slo
rules:
- alert: AtlasApiFastBudgetBurn
expr: |
(service:slo_errors_per_request:ratio_rate1h{service="atlas-api"} > 0.0144)
and
(service:slo_errors_per_request:ratio_rate5m{service="atlas-api"} > 0.0144)
for: 5m
keep_firing_for: 10m
labels:
severity: page
service: atlas-api
annotations:
summary: "atlas-api 正在快速消耗错误预算"
impact: "结算 API 的有效请求失败或超时"
dashboard: "https://grafana.example/d/atlas-api"
runbook: "https://runbooks.example/atlas-api/budget-burn"两个窗口都超阈值才进入 pending;同一标签集连续满足 for: 5m 后才 firing。这会增加检测延迟,应算进预算,而不是无条件复制。Prometheus 按表达式返回的向量元素创建告警,不能把 > 换成 > bool:后者也会返回值为 0 的元素。
keep_firing_for: 10m 在条件不再满足后保留 firing,短暂缺数也可能被它掩盖。它不会把缺失证明为恢复;仍要有独立的采集健康告警。具体阈值、窗口和附加延迟应一起推导。
规则还需要单元测试:正常、阈值边界、持续触发、数据缺失和恢复序列都要覆盖。
Alertmanager 处理通知拓扑
Prometheus 决定“什么条件正在告警”,Alertmanager 负责去重、分组、路由、静默和抑制。
下面补齐 receiver 定义以展示可校验的配置结构;示例 URL 必须替换为实际通知集成,并配置所需凭据。解析成功不代表 webhook 会被送达:
route:
receiver: default-ticket
group_by: [alertname, service, cluster]
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- matchers:
- severity="page"
receiver: primary-oncall
receivers:
- name: default-ticket
webhook_configs:
- url: https://notifications.example/tickets
- name: primary-oncall
webhook_configs:
- url: https://notifications.example/oncallgroup_wait 是新分组首条通知的等待,group_interval 控制后续组变化的通知节奏,repeat_interval 控制未变化告警的重复提醒;它们与规则的 for 是不同计时器。group_by 太细会让一次故障产生数百条通知,太粗又会把不同责任人的事件塞在一起。分组键应保留责任域和故障域,而不是把 pod、instance 等易变化维度默认带进去。
Inhibition 表达“根因告警存在时,抑制同范围的症状告警”,例如集群网络中断时抑制同集群的单服务不可达。要用明确的 source/target matcher 和相等的故障域标签限制范围;它并不自动推断根因,只抑制通知,不让原规则停止 firing。Silence 是有期限、带创建者和原因的人工匹配规则,适合计划维护;它不是删除坏告警的长期仓库。
高可用 Alertmanager 部署还要验证通知链路本身。仅监控每个组件进程存活,不足以证明告警能从规则一路送达值班终端,应定期运行端到端 canary 通知。
Dashboard 按问题分层
一个服务诊断界面可分三层:
第 1 层:用户是否受影响?
SLO、请求量、错误比例、延迟分布
第 2 层:影响在哪里?
region、version、route、dependency、tenant tier
第 3 层:为什么?
饱和度、队列、连接池、GC、下游延迟、trace/log 跳转首屏不要堆满 CPU、内存和几十条节点曲线。先给出范围、时间、单位、目标线和发布注释,让值班者在一分钟内判断影响。然后允许从稳定的低基数维度下钻。
面板标题应写成它回答的问题,例如“过去 30 分钟哪些区域正在消耗预算”,而不是“Error Graph 7”。百分比统一 0–1 或 0–100 的显示约定,延迟使用秒或毫秒时要在标题和轴上明确。
把变更放进同一时间轴
大量事故与发布、配置、扩容和依赖变更相关。Dashboard 应能叠加 deployment revision、feature flag、schema migration 和 incident annotation,并从异常点链接到:
- 当前运行的 image digest;
- 对应 Git commit 和发布审批;
- 代表性 trace;
- 限定 service、region、version 的日志查询。
这比继续增加十个资源面板更接近根因。
告警评审是持续工作
每次事件后记录:哪些告警率先提供有效信号,哪些重复、迟到或缺少上下文,哪些本应触发却沉默。对每条 page 统计频率、确认时间、是否可操作和自动恢复比例;长期无需人工行动的 page 应降级、合并或删除;若确实需要行动却无人响应,应修复值班路由和责任归属,不能靠删告警解决。
下一课补上服务端遥测看不到的部分:真实用户体验、合成探测、版本化配置和遥测成本控制。
参考资料
Prometheus, Alerting practices
Prometheus, Alerting rules
Prometheus, Alertmanager
Prometheus, Alertmanager configuration
Google SRE, Alerting on SLOs
Prometheus, Rule unit tests