4. 告警规则分层设计:Page、Ticket 与通知级别

在误差预算告警体系中,单一阈值无法同时满足“快速发现”与“避免噪音”的双重需求。本章基于燃烧速率(Burn Rate)理论,将告警划分为三个独立层级:Page(页面)、Ticket(工单)与通知(Notification)。每一层级对应不同的燃烧速率阈值、响应时效与升级路径,从而在 SLO 违例发生时,让正确的人以正确的速度介入。

4.1 燃烧速率与告警层级映射

燃烧速率衡量错误预算消耗的速度。1 倍燃烧速率意味着恰好按 SLO 设定的速率消耗预算;速率越高,SLO 违例风险越大。下表展示了三个层级与燃烧速率的对应关系:

告警层级 燃烧速率阈值 典型响应时间 接收者 示例场景
Page > 36 < 5 分钟 值班工程师(On-Call) 大规模故障、完全不可用
Ticket > 6 < 1 小时 SRE 团队 / 服务 Owner 部分功能降级、持续高延迟
通知 > 1 下一个工作日 开发团队 / 技术经理 轻微性能退化、预算消耗趋势异常
关键原则:燃烧速率越高,告警窗口越短。Page 级别使用短时间窗口(如 1 分钟)检测突发故障;通知级别使用长窗口(如 1 小时)过滤瞬时抖动,只暴露持续趋势。

4.2 三层告警规则详解

4.2.1 Page 级别(燃烧速率 > 36)

Page 是最高优先级的告警,代表错误预算正在以极快速度燃烧。36 倍燃烧速率意味着:如果持续 1 分钟,相当于在 36 分钟内消耗完整个月的错误预算。此类告警必须立即触发值班工程师响应。

  • 窗口长度:1 分钟(评估周期)
  • 触发条件:在 1 分钟窗口内,错误率超过 SLO 目标错误率的 36 倍。
  • 动作:自动创建 PagerDuty / OpsGenie 事件,电话或短信通知。
  • 防噪措施:仅当连续 2 个评估周期均满足条件时才触发,避免单次毛刺。
# Prometheus Recording Rule 示例(Page 级别)
- record: job:slo_errors_burn_rate_1m
  expr: |
    sum(rate(http_requests_total{status=~"5.."}[1m]))
    /
    sum(rate(http_requests_total[1m]))
    / on() group_left()
    (1 - slo_target)

# Alerting Rule
- alert: HighBurnRate_Page
  expr: job:slo_errors_burn_rate_1m > 36
  for: 2m
  labels:
    severity: page
    burn_rate: "36"
  annotations:
    summary: "错误预算燃烧速率超过 36 倍(Page 级别)"

4.2.2 Ticket 级别(燃烧速率 > 6)

Ticket 级别用于检测中等严重程度的持续问题。6 倍燃烧速率意味着在 10 分钟内消耗完月度预算。此类告警不需要立即电话通知,但应在 1 小时内创建工单并分配责任人。

  • 窗口长度:5 分钟(评估周期)
  • 触发条件:在 5 分钟窗口内,错误率超过 SLO 目标错误率的 6 倍。
  • 动作:自动创建 Jira / ServiceNow 工单,发送邮件或 Slack 通知。
  • 防噪措施:与 Page 级别互斥——如果 Page 级别已触发,则抑制 Ticket 告警。
# Prometheus Recording Rule 示例(Ticket 级别)
- record: job:slo_errors_burn_rate_5m
  expr: |
    sum(rate(http_requests_total{status=~"5.."}[5m]))
    /
    sum(rate(http_requests_total[5m]))
    / on() group_left()
    (1 - slo_target)

# Alerting Rule
- alert: HighBurnRate_Ticket
  expr: job:slo_errors_burn_rate_5m > 6
  for: 5m
  labels:
    severity: ticket
    burn_rate: "6"
  annotations:
    summary: "错误预算燃烧速率超过 6 倍(Ticket 级别)"

4.2.3 通知级别(燃烧速率 > 1)

通知级别是最低优先级的告警,用于趋势预警。1 倍燃烧速率意味着错误预算正在按 SLO 设定的速率消耗——如果持续下去,月底将恰好用尽预算。此类告警不要求立即行动,但应纳入日常回顾。

  • 窗口长度:30 分钟(评估周期)
  • 触发条件:在 30 分钟窗口内,错误率超过 SLO 目标错误率的 1 倍。
  • 动作:发送 Slack 消息或邮件摘要,不创建工单。
  • 防噪措施:仅在燃烧速率持续高于 1 倍超过 30 分钟时触发,避免短期波动。
# Prometheus Recording Rule 示例(通知级别)
- record: job:slo_errors_burn_rate_30m
  expr: |
    sum(rate(http_requests_total{status=~"5.."}[30m]))
    /
    sum(rate(http_requests_total[30m]))
    / on() group_left()
    (1 - slo_target)

# Alerting Rule
- alert: BurnRateWarning_Notification
  expr: job:slo_errors_burn_rate_30m > 1
  for: 30m
  labels:
    severity: notification
    burn_rate: "1"
  annotations:
    summary: "错误预算燃烧速率超过 1 倍(通知级别)"

4.3 层级联动与抑制策略

三个层级并非独立运行,而是通过抑制(Inhibition)与依赖(Dependency)规则形成联动体系。下图展示了告警触发后的决策流程:

告警层级联动与抑制决策流程 燃烧速率计算 速率 > 36? Page 告警 速率 > 6? Ticket 告警 速率 > 1? 通知告警 无动作 抑制 抑制 高优先级告警触发时, 自动抑制低优先级告警
最佳实践:在 Alertmanager 中配置 inhibit_rules,使 Page 级别告警自动抑制同源的 Ticket 和通知级别告警。这能显著减少告警风暴,让值班工程师只关注最高优先级的事件。

4.4 阈值联动与多窗口验证

单一窗口的燃烧速率可能因短期波动产生误报。推荐使用多窗口验证策略:同时评估短窗口(1 分钟)和长窗口(5 分钟)的燃烧速率,仅当两者均超过阈值时才触发告警。下表展示了不同窗口组合的联动效果:

告警层级 短窗口 长窗口 联动条件 误报率降低
Page 1 分钟 > 36 5 分钟 > 6 两个窗口同时满足 ~70%
Ticket 5 分钟 > 6 30 分钟 > 1 两个窗口同时满足 ~60%
通知 30 分钟 > 1 6 小时 > 0.5 两个窗口同时满足 ~50%
注意:多窗口联动会增加 Prometheus 查询复杂度。建议使用 Recording Rule 预计算各窗口的燃烧速率,避免 Alerting Rule 中重复计算。同时,确保长窗口的评估周期与告警的 for 参数协调,防止告警延迟过高。

4.5 层级告警的运维效果

在生产环境中实施三层告警分层后,典型效果如下:

  • Page 告警数量减少 80%:只有真正的紧急故障才会触发电话通知。
  • Ticket 告警可追溯性提升:每个工单都附带燃烧速率历史,便于事后分析。
  • 通知告警成为趋势指标:开发团队通过每日通知摘要,提前发现代码变更引入的退化。
  • 值班工程师疲劳度显著下降:从平均每天 15 次告警降至 2-3 次,且均为高价值事件。