土法炼钢 · 系统与基础设施

【可观测性工程】告警体系:Alertmanager、PagerDuty、OnCall 与分级抑制

文章导航

分类入口
architectureobservability
标签入口
#alertmanager#pagerduty#oncall#alerting#prometheus#slo#escalation#inhibition

目录

告警体系:Alertmanager、PagerDuty、OnCall 与分级抑制

凌晨 3 点,值班手机响了。不是一次。是 87 次。同一个上游依赖超时引发了连锁反应——87 条告警,其中 85 条是下游服务”我也超时了”的抱怨,只有最后 2 条是说”上游 Connection Pool 耗尽了”——真正的根因。值班人花了 40 分钟在手机屏幕上翻到第 86 条。

SLO 工程 定义了”什么算用户影响”——Burn Rate 告警。本文回答下一个问题:Burn Rate 触发了之后,告警怎么路由、怎么合并、怎么抑制、怎么叫醒正确的人,且不让值班人在 87 条通知里迷失?

Alertmanager 是 Prometheus 生态中专门负责”告警治理”的组件。它的设计目标不是”转发所有 firing alert”,而是 grouping + inhibition + silence + route 四元组,把数百条底层规则压缩成少量可行动的通知。文中配置结构按 Prometheus Alertmanager 0.27 官方文档(A 级来源)编写;本环境未安装 Alertmanager / amtool,配置语法以文档为准,部署前请在目标集群执行 amtool check-config(见附录 K)。

Alertmanager 告警治理流水线

一、告警体系的分层架构

从 Prometheus Alert Rule 到值班手机的完整路径可以拆成八层。每一层解决不同问题;跳过任何一层都会在生产环境中以”告警风暴”或”该响不响”的形式反弹。

层级 组件 职责 典型失败模式
L1 规则 Prometheus alerting rules 定义”什么算异常” 阈值拍脑袋、无 runbook
L2 记录 Recording rules 预计算 Burn Rate 等 SLI 规则未部署到 HA 副本
L3 路由 Alertmanager route 按 label 选 receiver 所有 critical 都打 Page
L4 分组 group_by + timing 合并同源告警 group_wait 太短
L5 抑制 inhibit_rules 隐藏衍生告警 规则过宽误抑制
L6 静默 silence / time_intervals 维护窗口屏蔽 静默过期未清理
L7 通知 receivers (webhook/PagerDuty) 送达渠道 webhook 429 丢通知
L8 排班 PagerDuty / Opsgenie 谁在值班、如何升级 排班表过期

1.1 数据流概览

flowchart LR
  subgraph prom [Prometheus]
    AR[Alert Rules]
    RR[Recording Rules]
  end
  subgraph am [Alertmanager HA Cluster]
    RT[Route Tree]
    GR[Grouping]
    IN[Inhibition]
    RC[Receivers]
  end
  subgraph notify [Notification]
    PD[PagerDuty Page]
    JK[Jira Ticket]
    SL[Slack Chat]
    DB[Dashboard Log]
  end
  AR --> RT
  RR --> AR
  RT --> GR --> IN --> RC
  RC --> PD
  RC --> JK
  RC --> SL
  RC --> DB

1.2 Rules 层:与 SLO 的衔接

SLO 工程 §4 给出 6 条 Workbook 规则——3 条 Page、3 条 Ticket。Alertmanager 不修改 这些规则的 expr,只根据 labels.severity 路由:

Prometheus label Alertmanager 路由 通知渠道
severity: page receiver: pagerduty-oncall 电话 + SMS
severity: ticket receiver: jira-sre 工单
severity: chat receiver: slack-infra Slack 频道
severity: log receiver: blackhole 或 null 仅 Grafana

反模式:在 Prometheus 规则里写 severity: critical 却期望 Alertmanager 自动区分 Page 和 Ticket——critical 没有统一定义,必须显式使用 page / ticket / chat / log 四级(或团队等价命名,但文档化)。

1.3 与指标体系的关系

指标体系设计 中的 USE/RED 指标是 Ticket 和 Chat 级 的主要输入——CPU 饱和、磁盘错误、连接池使用率。它们解释 SLO 失败的根因,但不应直接触发 Page。唯一应触发 Page 的指标类告警是 SLO Burn Rate(及等价的全站 outage 探测)。

二、告警规则设计的铁律

Google SRE Book 第 6 章:一个好的告警必须满足 actionable——收到它的人知道该做什么,且不做就会造成伤害或错过修复窗口。

2.1 四大黄金法则

  1. Actionable(可操作):告警必须链到 runbook 第一步。Runbook 第一句不是”调查一下”,而是”打开 Dashboard X,确认指标 Y,若 Z 则执行 W”。
  2. Owner(有主)team label 指向负责团队。无 owner 的告警在 on-call 眼里等于 spam。
  3. Priority(有优先级):与 Alertmanager route 一致的 severity label。
  4. Runbook(有手册)runbook_url 必须是稳定 URL——不要用 Confluence 无版本页面。

2.2 必须标签模板

# 每条 alerting rule 的 labels 最小集
labels:
  severity: page          # page | ticket | chat | log
  team: checkout
  service: checkout-api
  runbook_url: "https://wiki.example.com/runbooks/checkout-burn-rate"
# annotations 最小集
annotations:
  summary: "checkout SLO 1h 燃烧率 {{ $value | printf "%.1f" }}×"
  description: |
    当前 1 小时窗口 Burn Rate 超过 14.4×,预计 30 天内消耗约 2% 错误预算。
    Dashboard: https://grafana.example.com/d/slo-checkout
    Runbook: {{ $labels.runbook_url }}

2.3 规则分层:Page / Ticket / Chat / Log

级别 触发条件(与 SLO 联动) 响应 SLA 示例
Page Burn Rate ≥ 14.4×/1h 或 6×/6h 或 1×/3d(见 18-slo §4.1) 5 min ack CheckoutSLOBurnRateCritical1h
Ticket Burn Rate ≥ 1×/6h 或 Workbook Ticket 规则 1 h CheckoutSLOBurnRateWarning6h
Chat 容量趋势、复制 lag、慢查询增长 工作时间 PGReplicationLagHigh
Log 非生产、周期性 cron 信息 StagingDeployComplete

2.4 反例目录

以下规则在多数团队应 降级或删除

反例规则 问题 建议
CPU > 80% → Page 不等价用户影响 改为 Chat;Page 只看 Burn Rate
Pod restart > 3 → Page 可能是正常滚动发布 Ticket + 关联 deployment 事件
Disk > 85% → Page 有缓冲时间 Ticket,7 天趋势 Chat
Any 5xx > 0 → Page 瞬时尖峰误报 用 Burn Rate 或 for: 5m
cert expires in 30d → Page 有充足修复窗口 Ticket 30d,Chat 7d

2.5 PromQL 规则写作规范

groups:
  - name: slo_checkout_pages
    interval: 30s
    rules:
      - alert: CheckoutSLOBurnRateCritical1h
        expr: slo:checkout:burnrate1h > 14.4
        for: 2m
        labels:
          severity: page
          team: checkout
          service: checkout-api
          runbook_url: "https://wiki.example.com/runbooks/checkout-slo"
        annotations:
          summary: "checkout 1h Burn Rate {{ $value | printf "%.2f" }}×"
          description: "Page 级 SLO 告警。见 18-slo Workbook 规则 A。"

      - alert: CheckoutSLOBurnRateWarning6h
        expr: slo:checkout:burnrate6h > 1
        for: 15m
        labels:
          severity: ticket
          team: checkout
          service: checkout-api
          runbook_url: "https://wiki.example.com/runbooks/checkout-slo-ticket"
        annotations:
          summary: "checkout 6h Burn Rate {{ $value | printf "%.2f" }}×"

for: 子句是降噪关键——Workbook 建议 Page 规则 2–5 分钟 pending,Ticket 15 分钟至 1 小时。

三、Alertmanager 深度实战

Alertmanager 配置四大核心块:globalroutereceiversinhibit_rules。Alertmanager 0.27+ 还支持 time_intervals 用于维护窗口路由。

3.1 完整 alertmanager.yml 示例

以下配置为合成示例,展示 route 树、多 receiver、inhibit、time_intervals 的完整结构。Webhook URL 和 integration key 为占位符——部署时替换为真实值。

# alertmanager.yml — 合成生产级示例
# 验证:amtool check-config alertmanager.yml
# 参考:Prometheus Alertmanager 0.27 官方文档

global:
  resolve_timeout: 5m
  smtp_smarthost: 'smtp.example.com:587'
  smtp_from: 'alertmanager@example.com'
  smtp_auth_username: 'alertmanager@example.com'
  smtp_auth_password: '<secret>'
  slack_api_url: '<slack-webhook-url>'

templates:
  - '/etc/alertmanager/templates/*.tmpl'

# --- time_intervals:维护窗口 ---
time_intervals:
  - name: weekday-business-hours
    time_intervals:
      - weekdays: ['monday:friday']
        times:
          - start_time: '09:00'
            end_time: '18:00'
        location: 'Asia/Shanghai'

  - name: planned-maintenance
    time_intervals:
      - weekdays: ['saturday']
        times:
          - start_time: '02:00'
            end_time: '06:00'
        location: 'Asia/Shanghai'

# --- route 树 ---
route:
  receiver: 'default-slack'
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h

  routes:
    # 计划维护:非 Page 告警静默路由到 blackhole
    - matchers:
        - severity=~"chat|log|ticket"
      mute_time_intervals:
        - planned-maintenance
      receiver: 'blackhole'
      continue: false

    # Page:SLO Burn Rate → PagerDuty
    - matchers:
        - severity="page"
      receiver: 'pagerduty-primary'
      group_wait: 10s
      group_interval: 2m
      repeat_interval: 1h
      continue: true

    # Ticket → Jira
    - matchers:
        - severity="ticket"
      receiver: 'jira-sre'
      group_wait: 1m
      group_interval: 10m
      repeat_interval: 12h
      continue: true

    # Chat → Slack 分团队
    - matchers:
        - severity="chat"
        - team="checkout"
      receiver: 'slack-checkout'
      continue: true

    - matchers:
        - severity="chat"
        - team="platform"
      receiver: 'slack-platform'
      continue: true

    # Log 级:不通知
    - matchers:
        - severity="log"
      receiver: 'blackhole'
      continue: false

    # 兜底:未匹配 severity 的告警
    - matchers:
        - severity=~"critical|warning"
      receiver: 'slack-sre-escalation'
      continue: false

# --- inhibit_rules ---
inhibit_rules:
  # 集群级网络故障抑制 per-target 不可达
  - source_matchers:
      - alertname="NetworkDown"
      - severity="page"
    target_matchers:
      - alertname=~"TargetDown|KubeletDown|NodeNotReady"
    equal: ['cluster']

  # Page 级 SLO 抑制同 service 的 Ticket
  - source_matchers:
      - severity="page"
    target_matchers:
      - severity="ticket"
    equal: ['service']

  # 上游 checkout 依赖故障抑制下游 timeout 类 Chat
  - source_matchers:
      - alertname="CheckoutDependencyDown"
      - severity=~"page|ticket"
    target_matchers:
      - alertname=~"DownstreamTimeout.*"
    equal: ['cluster', 'upstream']

  # 全站 outage 抑制单服务 degraded(保留 Page 本身)
  - source_matchers:
      - alertname="GlobalOutage"
      - severity="page"
    target_matchers:
      - severity="chat"
    equal: ['cluster']

# --- receivers ---
receivers:
  - name: 'blackhole'

  - name: 'default-slack'
    slack_configs:
      - channel: '#alerts-unrouted'
        send_resolved: true
        title: '{{ .GroupLabels.alertname }}'
        text: '{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}'

  - name: 'pagerduty-primary'
    pagerduty_configs:
      - routing_key: '<pagerduty-events-api-v2-key>'
        severity: '{{ if eq .CommonLabels.severity "page" }}critical{{ else }}warning{{ end }}'
        description: '{{ .CommonAnnotations.summary }}'
        details:
          firing: '{{ .Alerts.Firing | len }}'
          service: '{{ .CommonLabels.service }}'
          runbook: '{{ .CommonLabels.runbook_url }}'

  - name: 'jira-sre'
    webhook_configs:
      - url: 'https://jira-bridge.example.com/create-ticket'
        send_resolved: true
        http_config:
          bearer_token: '<token>'

  - name: 'slack-checkout'
    slack_configs:
      - channel: '#team-checkout-alerts'
        send_resolved: true

  - name: 'slack-platform'
    slack_configs:
      - channel: '#team-platform-alerts'
        send_resolved: true

  - name: 'slack-sre-escalation'
    slack_configs:
      - channel: '#sre-unlabeled-alerts'
        send_resolved: true
        title: '未分级告警需人工标注 severity'

3.2 Route 树设计原则

  1. 最具体的路由在前team=checkout 应在通用 severity=chat 之前(Alertmanager 按顺序匹配第一个 hit)。
  2. continue: true 用于 Page + Slack 双通道:Page 到 PagerDuty 的同时抄送 Slack war room——但避免 Ticket 也双发 Page。
  3. repeat_interval 按 severity 分级:Page 1h 重复可接受;Chat 可 24h。
  4. 兜底 receiver 必须存在:未匹配路由的告警进 #sre-unlabeled-alerts,每周清理并补 label。

3.3 Grouping 工程细节

Alertmanager grouping 的三个时间参数(官方文档定义):

参数 含义 推荐起点 设错后果
group_wait 同组首条告警后等待多久再发送 Page 10–30s,Ticket 1–5m 太短→多条通知;太长→Page 延迟
group_interval 同组新增告警的最小通知间隔 2–10m 太短→风暴;太长→信息滞后
repeat_interval 未 resolve 时重发间隔 Page 1–4h,Ticket 12–24h 不设→默认 4h;设 0→非法

group_by 标签选择:

# 推荐:按 alertname + 故障域
group_by: ['alertname', 'cluster', 'service']

# 反例:group_by: ['instance'] — 100 台机器 = 100 组通知
# 反例:group_by: [] — 所有告警一组,无关告警捆绑

工程判断:Burn Rate Page 应按 service 分组——checkout 和 payment 同时 Burn 时应是两条 Page,不是一条。

3.4 Inhibition 规则设计

Inhibition 语法(Alertmanager 0.27+ 使用 matchers):

设计 checklist:

  1. 画依赖图:上游挂 → 哪些下游 alert 必然 firing?
  2. 每条 inhibit 写注释说明假设
  3. 避免 equal: [] 过宽抑制
  4. 在 staging 用 amtool 或 UI 验证抑制是否误伤
# 示例:数据库只读模式抑制所有 query timeout Chat
- source_matchers:
    - alertname="PostgreSQLReadOnly"
    - severity=~"page|ticket"
  target_matchers:
    - alertname="QueryTimeoutHigh"
  equal: ['cluster', 'database']

3.5 time_intervals 与维护窗口

mute_time_intervals 挂在 route 上——维护期间 Ticket/Chat 进 blackhole,Page 不应 mute(除非确认无用户流量)。

# 仅非 Page 路由挂 mute
- matchers:
    - severity=~"ticket|chat|log"
  mute_time_intervals:
    - planned-maintenance
  receiver: 'blackhole'

维护前创建 Silence(UI 或 amtool)覆盖已知 firing 规则,比永久改 route 更安全——Silence 有过期时间。

四、告警风暴:机制与治理

4.1 风暴如何形成

典型链路:上游 Redis 连接池耗尽 → 50 个微服务 timeout → 每个服务 3 条规则(latency、error rate、health check)→ 150 条 firing alert → 若 group_by: ['instance'] 且无 inhibit → 150 条 Slack/PagerDuty 通知。

sequenceDiagram
  participant Redis as Redis 连接池
  participant Up as checkout-api
  participant Down as 50 下游服务
  participant Prom as Prometheus
  participant AM as Alertmanager
  participant OC as OnCall 手机

  Redis->>Up: 连接超时
  Up->>Down: 级联 timeout
  loop 每服务 3 规则
    Prom->>Prom: 评估 alert 规则
  end
  Prom->>AM: 150 alerts firing
  Note over AM: group_wait 过短<br/>无 inhibit
  AM->>OC: 87 条 Page/Slack
  OC->>OC: 40 min 找根因
  Note over OC: 应只收到 1 条<br/>CheckoutDependencyDown Page

4.2 风暴治理三板斧

  1. InhibitionCheckoutDependencyDown page 抑制 DownstreamTimeout*
  2. Groupinggroup_by: ['alertname','service']group_wait: 30s
  3. 规则减量:删除”每条 5xx 都 Page”类规则,统一为 Burn Rate

4.3 风暴事后复盘模板

字段 内容
根因 alert CheckoutRedisPoolExhausted
衍生 alert 数量 148
实际通知数 87
应通知数 2(1 Page + 1 Ticket)
修复动作 新增 inhibit;合并规则
误报标注 85 条标注为 duplicate

五、分级告警体系设计模板(与 SLO Burn Rate 绑定)

本节将 SLO 工程 §4 的 Workbook 阈值映射到 Alertmanager 路由与 OnCall 响应。这是全文的决策核心

5.1 四级定义与 Burn Rate 对照

级别 Burn Rate 条件(30d SLO=99.9%) Alertmanager receiver OnCall 动作
Page 1h ≥ 14.4× 或 6h ≥ 6× 或 3d ≥ 1×(持续) pagerduty-primary 5 min ack,开 war room
Ticket 6h ≥ 1× 或 1d ≥ 1× 或 3d ≥ 1×(未达 Page) jira-sre 1 h 内认领
Chat 无 Burn Rate;容量/趋势类 slack-* 工作时间处理
Log 非 prod、信息性 blackhole 仅 Dashboard

Burn Rate 定义(摘自 18-slo):

\[\text{burn\_rate} = \frac{\text{error\_rate}}{1 - \text{SLO}}\]

对 99.9% SLO,\((1 - \text{SLO}) = 0.001\)。14.4×/1h 表示按当前错误率,约 1 小时消耗 30 天预算的 2%。

5.2 端到端映射表

Prometheus alert severity Burn Rate expr AM route PD urgency
CheckoutSLOBurnRateCritical1h page burnrate1h > 14.4 pagerduty high
CheckoutSLOBurnRateCritical6h page burnrate6h > 6 pagerduty high
CheckoutSLOBurnRateCritical3d page burnrate3d > 1 pagerduty high
CheckoutSLOBurnRateWarning6h ticket burnrate6h > 1 jira low
CheckoutSLOBurnRateWarning1d ticket 1d window > 1× jira low
CheckoutSLOBurnRateWarning3d ticket 3d window > 1× jira low
NodeDiskTrend7d chat N/A slack-platform
StagingDeployOK log N/A blackhole

5.3 Page 准入清单

满足 任一 才可 Page:

  1. 用户 facing SLO Burn Rate 达 Workbook Page 阈值
  2. 合成探测确认全站 outage(blackbox probe_success == 0 持续 2m,且影响 prod)
  3. 安全事件(未授权访问 confirmed)——超出本文范围,走安全 runbook

永不 Page:CPU、内存、磁盘百分比、单 Pod restart、cron 失败(除非 cron 是支付链路 SLI 组成部分)。

5.4 Ticket 与 Chat 边界

信号 级别 理由
PG 复制 lag > 30s Chat → Ticket 若持续 1h 未直接 Burn API SLO
API Burn Rate 1×/6h Ticket Workbook 规则 D
证书 14 天过期 Chat 有修复窗口
错误预算剩余 < 20%(Dashboard) Chat 通知 TL 非即时技术响应

5.5 分级 policy 文档片段(可粘贴到内部 wiki)

## Error Budget Alerting Policy v1.2

### Page(立即)
- 条件:任一用户 facing 服务触发 SLO Burn Rate Page 规则(见 Grafana dashboard slo-pages)
- 响应:5 分钟内 PagerDuty ack;15 分钟内 incident commander
- Override:仅 SRE Lead 可 suppress Page(需事后复盘)

### Ticket(1 小时)
- 条件:Burn Rate Ticket 规则 或 非 SLO 但影响单一内部系统
- 响应:Jira 工单 1 小时内认领

### Chat(工作时间)
- 条件:容量、趋势、非用户 facing 退化
- 响应:下一工作日 standup 跟进

### Log
- 条件:staging、信息性事件
- 响应:无

六、PagerDuty 与 OnCall 工程

OnCall 升级状态机

6.1 排班模型

模型 适用 优点 缺点
每周轮换 小团队、单时区 简单 交接边界易漏
Follow-the-sun 全球三时区 本地时间 humane 协调成本高
主备叠加 关键支付链路 冗余 两人同时被叫风险

PagerDuty Schedule 定义”谁值班”;Escalation Policy 定义”无 ack 时叫谁”。

6.2 升级策略示例

stateDiagram-v2
  [*] --> Triggered: Alertmanager Page
  Triggered --> Acknowledged: L1 ack 5min内
  Triggered --> EscalatedL2: 5min 无 ack
  Acknowledged --> Investigating: 打开 runbook
  Investigating --> Resolved: 修复验证
  EscalatedL2 --> EscalatedL3: 15min 仍无 ack
  EscalatedL3 --> Resolved: SRE Lead 介入
  Resolved --> [*]
级别 等待 目标 通知方式
L1 0 Primary on-call Push + 电话
L2 5 min Secondary backup 电话
L3 15 min SRE Lead 电话 + Slack exec

6.3 Incident 生命周期

PagerDuty Incident 状态:triggeredacknowledgedresolved。严格流程:

  1. Trigger:Alertmanager 通过 Events API v2 创建 incident
  2. Ack:L1 确认”我在处理”——不是”我看到了 Slack”
  3. Resolve:Prometheus alert 恢复后 Alertmanager 发 resolved——PD 可 auto-resolve(需配置)
# Alertmanager pagerduty_configs 片段
pagerduty_configs:
  - routing_key: '<integration-key>'
    send_resolved: true
    class: '{{ .CommonLabels.service }}'
    component: '{{ .CommonLabels.alertname }}'
    group: 'slo'
    severity: 'critical'

6.4 Runbook 必备结构

  1. 症状:Burn Rate 14×/1h,checkout 5xx 上升
  2. 诊断三步:Grafana SLO 面板 → 依赖 RED 面板 → 最近 deployment(Events
  3. 缓解:回滚 / 扩容 / 熔断——每步有命令
  4. 验证:Burn Rate 回落、SLI 恢复
  5. 升级条件:15 min 无进展 → 叫 DBRE / 架构师

6.5 值班疲劳度指标

指标 健康范围 超标动作
alerts_per_oncall_shift < 5 需人工介入 告警审计
false_positive_rate < 20% 调阈值 / 加 for
mean_time_to_ack < 5 min(Page) 排班或 PD 配置
pages_without_incident < 10%/月 规则降级

七、告警质量的持续治理

告警体系 6–12 个月无治理会退化为”全部 mute”。

7.1 每周告警审计

从 Alertmanager 或 Grafana OnCall 导出:

  1. 触发次数 Top 10 规则
  2. 无 ack 规则
  3. 同一 alert 重复 > 10 次/shift

对每条:actionable? → 否 → 删除;是但非紧急 → 降级 severity。

7.2 告警归因

每条 Page 事后必须:

未归因 Page 在月度 SLO 评审(18-slo §7.3)中问责。

7.3 季度清理 Sprint

7.4 Alertmanager 高可用

单实例 Alertmanager 挂掉 → 告警路由停止。最小 HA:

Prometheus HA §Alertmanager 部署。

八、工程坑点(真实场景)

8.1 group_wait 设太短

现象:同一 Redis 故障,3 秒内收到 checkout、payment、cart 三条 Page。

原因group_wait: 0 或 5s,三个 service 的 alert 分属不同 group(group_byservice)。

修复

8.2 repeat_interval 误解

现象:告警恢复后仍每小时收到重复 Page。

原因repeat_interval: 1h 且 alert 在阈值边界抖动(flapping)。

修复

8.3 Webhook 限流与丢失

现象:Slack/钉钉/飞书”有时收不到告警”。

原因:Webhook 429/5xx,Alertmanager 不重试无限次——失败通知丢失。

缓解

8.4 severity=critical 无 escalation

现象:critical 告警进 Slack 无人看。

修复:统一 severity 枚举与 route 一致;unlabeled 进 #sre-unlabeled-alerts 并 weekly 修复。

8.5 Inhibition 过宽

现象:真实故障被 suppress——Payment 真正挂时 checkout 的 Page 被误抑制。

修复equalservice;staging 测试 inhibit;文档化每条规则假设。

8.6 Alertmanager 与 Prometheus 标签不一致

现象:route 匹配不到,severity=page 进了 default-slack。

修复:CI 中 promtool check rules + amtool check-config;单元测试 alert label 集合。

8.7 send_resolved: false 的取舍

恢复通知丢失时 on-call 不知道何时停 war room——建议 Page 通道 send_resolved: true;Chat 可 false 减噪。

九、与 Prometheus HA 的集成

9.1 双 Prometheus 单 Alertmanager 集群

两个 Prometheus 实例评估相同规则 → 可能 duplicate alert。Alertmanager 通过 gossip 去重 相同 fingerprint 的 alert。

配置:

# prometheus.yml
alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager-1:9093
            - alertmanager-2:9093
            - alertmanager-3:9093

9.2 避免 alert 标签 churn

pod label 随滚动变化 → grouping 失效。SLO 规则应使用 servicedeployment 等稳定 label。


十、通知渠道集成要点

10.1 Slack

10.2 PagerDuty Events API v2

10.3 钉钉 / 飞书 Webhook

10.4 Email


十一、落地清单


十二、关键概念回顾


十三、下一步

告警体系就绪后,存储账单是下一个治理焦点——采样、保留期、冷热分层。下一篇 存储与成本


上一篇SLO 工程:错误预算、Burn Rate、多窗口告警

下一篇可观测性存储与成本

参考资料

  1. Prometheus, Alertmanager, https://prometheus.io/docs/alerting/latest/alertmanager/
  2. Prometheus, Configuration, https://prometheus.io/docs/alerting/latest/configuration/
  3. Google, The Site Reliability Workbook, Chapter 5: Alerting on SLOs, O’Reilly, 2018
  4. Google, Site Reliability Engineering, Chapter 6: Monitoring Distributed Systems, O’Reilly, 2016
  5. PagerDuty, Response, https://response.pagerduty.com/

附录 A:amtool 常用命令

# 验证配置
amtool check-config alertmanager.yml

# 查看当前活跃 alert(需连接 AM API)
amtool alert query

# 创建 2 小时 silence
amtool silence add alertname=CheckoutSLOBurnRateCritical1h \
  --comment "planned load test" \
  --duration 2h

# 测试 route(Alertmanager 0.27+)
amtool config routes test --config.file=alertmanager.yml \
  --tree --verify.receivers \
  severity=page service=checkout

本环境未安装 amtool——命令来自 Alertmanager 官方文档。


附录 B:告警模板 slack.tmpl

{{ define "slack.slo.title" }}
[{{ .Status | toUpper }}] {{ .CommonLabels.severity }}{{ .CommonLabels.service }}
{{ end }}

{{ define "slack.slo.text" }}
{{ range .Alerts }}
*{{ .Annotations.summary }}*
Burn Rate alert — Runbook: {{ .Labels.runbook_url }}
{{ end }}
{{ end }}

附录 C:Synthetic alert 测试步骤

  1. 在 staging Prometheus 注入高 error rate recording
  2. 确认 slo:*:burnrate1h 超阈值
  3. 观察 Alertmanager UI grouping
  4. 验证 PagerDuty staging service 收到 1 条 incident
  5. 恢复 error rate,确认 resolved 通知

附录 D:与 Chaos 工程衔接

混沌工程 实验前: - 创建 silence 覆盖预期 Chat 告警 - silence Page 规则——验证 Burn Rate 是否正常触发 - 实验后检查 false positive 归因


读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。

2026-04-22 · architecture / observability

可观测性工程

从 Metrics、Logs、Traces 到 Profiling、eBPF、OpenTelemetry 与 SLO 治理,面向中国工程团队的可观测性系统化手册。全 25 篇。


By .