3. 告警规则结构解析:Alerting Rule 的 YAML 结构、expr 表达式、for 持续时间、labels 与 annotations 设计
告警规则是 Prometheus 可观测性体系的“触发开关”。一个结构严谨的 Alerting Rule 不仅决定了告警是否准确,还直接影响后续的自愈剧本能否正确执行。本章将逐层拆解 Alerting Rule 的 YAML 骨架,深入分析 expr、for、labels 和 annotations 四个核心字段的设计原则与调优方法。
3.1 Alerting Rule 的完整 YAML 结构
一个标准的告警规则定义在 Prometheus 的 rules/*.yml 文件中,其顶层结构如下:
groups:
- name: <group_name> # 规则组名称,用于逻辑分组
interval: <evaluation_interval> # 该组规则的评估周期(可选,默认继承全局配置)
rules:
- alert: <alert_name> # 告警名称,必须唯一
expr: <promql_expression> # PromQL 表达式,触发条件
for: <duration> # 持续时间,防止抖动
labels: # 附加标签,用于路由与去重
<key>: <value>
annotations: # 注解,用于告警消息内容
<key>: <value>
设计要点: 规则组
group_name 建议按业务模块或告警级别命名(如 high_availability、performance_critical),便于后期维护与批量调优。
3.2 expr 表达式:告警触发的核心逻辑
expr 是 PromQL 表达式,它定义了“什么时候该告警”。表达式的结果必须是一个瞬时向量,且向量中的每个样本都代表一个潜在的告警实例。
| 表达式类型 | 示例 | 说明 |
|---|---|---|
| 阈值比较 | node_cpu_seconds_total > 0.9 |
当 CPU 使用率超过 90% 时触发 |
| 变化率检测 | rate(http_requests_total[5m]) < 100 |
5 分钟内请求速率低于 100 QPS |
| 缺失数据 | absent(up{job="api-server"}) == 1 |
目标实例完全无数据上报 |
| 聚合对比 | sum by (instance) (rate(cpu_seconds_total[1m])) > 0.8 |
按实例聚合后,任一实例 CPU 超过 80% |
常见陷阱: 避免在
expr 中使用 offset 或 @ 修饰符进行历史数据回溯,这会导致告警评估结果与当前时间窗口错位,增加自愈剧本的误判风险。
3.3 for 持续时间:消除抖动与误告警
for 字段定义了告警条件必须持续满足多长时间后,告警状态才会从 Pending 转为 Firing。这是防止瞬时峰值或网络抖动引发无效告警的关键参数。
# 示例:CPU 高负载持续 5 分钟才触发告警
- alert: HighCpuUsage
expr: node_cpu_seconds_total > 0.9
for: 5m
调优建议:
- 基础设施类告警(如 CPU、内存):推荐
for: 2m ~ 5m,避免毛刺。 - 业务类告警(如错误率、延迟):推荐
for: 30s ~ 1m,快速响应。 - 自愈剧本联动:如果自愈动作需要快速介入,
for不宜过长,建议 ≤ 2m。
自愈场景提示: 当
for 设置为 0 时,告警条件一旦满足立即触发 Firing。这在自愈剧本中可用于“零容忍”类告警(如进程崩溃),但需配合更严格的抖动抑制策略。
3.4 labels 设计:告警路由与去重标识
labels 是告警的元数据标签,用于告警分组、路由(如 Alertmanager 的 route 匹配)和去重。设计良好的 labels 能显著提升告警治理效率。
| 标签键 | 推荐值 | 作用 |
|---|---|---|
severity |
critical / warning / info |
告警级别,用于 Alertmanager 路由与通知优先级 |
team |
sre / backend / infra |
负责团队,用于告警分派 |
service |
api-gateway / user-service |
服务名称,用于告警聚合与自愈剧本匹配 |
action |
restart / scale-up / clean-cache |
自愈动作标识,直接驱动自愈剧本选择 |
# 自愈场景下的 labels 设计示例
- alert: ApiHighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
for: 1m
labels:
severity: critical
team: sre
service: api-gateway
action: restart-pod
设计原则: labels 应保持“少而精”。避免将动态变化的值(如当前 CPU 使用率)写入 labels,这会导致告警基数爆炸,影响 Alertmanager 性能。
3.5 annotations 设计:告警消息的内容模板
annotations 用于携带告警的详细描述、当前值、建议操作等人类可读信息。这些内容会直接出现在告警通知(邮件、钉钉、Slack)中,是值班人员的第一手资料。
| 注解键 | 推荐模板 | 说明 |
|---|---|---|
summary |
{{ $labels.instance }} CPU 使用率超过 90% |
简短总结,用于标题 |
description |
实例 {{ $labels.instance }} 当前 CPU 使用率为 {{ $value | humanizePercentage }},已持续 {{ $for }},请检查。 |
详细描述,包含当前值与持续时间 |
runbook_url |
https://wiki.xxx.com/runbooks/high-cpu |
应急预案链接,加速故障恢复 |
auto_recovery |
true / false |
自愈剧本是否自动执行,用于控制台展示 |
# 完整的 annotations 示例
annotations:
summary: "{{ $labels.instance }} 错误率过高"
description: "实例 {{ $labels.instance }} 在最近 5 分钟内的 5xx 错误率为 {{ $value | humanizePercentage }},超过阈值 5%。"
runbook_url: "https://runbook.team/api-error"
auto_recovery: "true"
注意事项: annotations 中可以使用
{{ $value }}、{{ $labels }} 等模板变量,但不要将大量原始指标数据塞入 description,避免通知消息过长。建议只包含关键指标与上下文。
3.6 结构总览:从 YAML 到告警生命周期的映射
下面的 SVG 图展示了 Alerting Rule 各字段在告警生命周期中的位置与作用:
3.7 字段设计对比速查表
以下表格总结了四个核心字段的设计目标与调优方向,便于在自愈剧本开发时快速参考:
| 字段 | 设计目标 | 调优方向 | 自愈剧本关联 |
|---|---|---|---|
expr |
精确描述触发条件 | 避免复杂聚合,优先使用 rate/increase 平滑指标 |
直接决定自愈动作的触发时机 |
for |
消除抖动,确认持续性 | 基础设施 2-5m,业务 30s-1m,自愈联动 ≤2m | 影响自愈剧本的响应延迟 |
labels |
路由、去重、分派 | 保持标签基数可控,severity/team/action 为必选 |
action 标签直接映射自愈剧本 ID |
annotations |
提供上下文与操作指引 | 使用模板变量,避免过长,包含 runbook_url |
auto_recovery 注解控制是否自动执行 |
实战建议: 在自愈剧本开发初期,建议先为每个告警规则定义
action 标签和 auto_recovery 注解。这样可以在不修改 PromQL 逻辑的前提下,通过调整 labels 和 annotations 快速切换自愈策略,实现“告警与自愈的解耦”。