3. Prometheus告警基础:架构、规则与Alertmanager

聊到告警,很多新手第一反应就是“配个阈值,超过就报警”。嗯,理论上没错。但实际落地时你会发现,告警系统的设计远比想象中复杂。我见过不少团队,告警配了一大堆,结果半夜全是垃圾告警,真正出问题的时候反而被淹没了。

今天这一章,我们就来拆解Prometheus告警的三大核心:架构怎么搭、规则怎么写、Alertmanager怎么用。说白了,就是让你从“能报警”进化到“会报警”。

Prometheus 告警核心架构 被监控目标 (Node/App/DB) Prometheus Server (抓取+存储+评估) Alertmanager (去重+分组+发送) 告警规则文件 通知渠道 数据流 → 规则评估 - - →

3.1 Prometheus 告警架构:谁在做什么?

先看整体流程。Prometheus 的告警体系分三层:采集层、评估层、通知层

  • 采集层:Prometheus Server 定期从目标拉取指标数据,存到本地TSDB。
  • 评估层:Server 内部有一个独立的告警规则评估器,每隔一定时间(默认1分钟)检查规则是否触发。
  • 通知层:一旦规则触发,Prometheus 会把告警推给 Alertmanager,由它负责去重、分组、抑制,最后发送通知。

关键点:Prometheus Server 只负责“判断是否告警”,不负责“怎么发通知”。发通知是 Alertmanager 的活儿。这个分离设计,我个人觉得非常优雅——职责单一,扩展性强。

我在项目中遇到过一种情况:团队直接把告警通知写在 Prometheus 的配置里,没用 Alertmanager。结果告警一多,邮箱直接被塞爆,而且重复告警满天飞。后来改成 Alertmanager 统一管理,世界清净了。

3.2 告警规则配置:怎么写才不“狼来了”?

告警规则写在 YAML 文件里,通过 rule_files 字段加载到 Prometheus 配置中。先看一个基础例子:

# prometheus.yml
rule_files:
  - "alerts/*.yml"

规则文件长这样:

groups:
  - name: node_alerts
    interval: 30s
    rules:
      - alert: HighCpuUsage
        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Instance {{ $labels.instance }} CPU usage over 80%"
          description: "CPU usage has been above 80% for more than 5 minutes."

拆开来看几个关键字段:

字段作用我的建议
alert告警名称,必须唯一命名要有规律,比如“服务名_指标名_异常类型”
exprPromQL 表达式,触发条件尽量用 rate()increase() 避免毛刺
for持续时间,防止瞬时报错这个字段太重要了!我见过不加 for 的,结果网络抖动一下告警就炸了
labels附加标签,用于路由建议加 severityteam,方便 Alertmanager 分组
annotations告警描述信息一定要写清楚“什么挂了”和“影响是什么”

避坑指南:我曾经把 for 设成 0s,结果一个高负载任务每次波动都触发告警。后来改成 5m,只有持续 5 分钟以上才报警,误报率直接降了 80%。

3.3 Alertmanager:告警的“交通警察”

Alertmanager 的核心职责就三个字:管、控、发

  • 分组(Grouping):把类似的告警合并成一条通知。比如 10 台机器同时 CPU 高,合并成一条“多台机器 CPU 异常”。
  • 抑制(Inhibition):如果某个高级别告警已经触发,自动屏蔽相关的低级别告警。比如“数据库挂了”时,就不用再报“数据库连接超时”了。
  • 静默(Silencing):在维护窗口期内,手动屏蔽某些告警。

看一个 Alertmanager 的配置示例:

route:
  receiver: 'default'
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - match:
        severity: critical
      receiver: 'pagerduty'
    - match:
        severity: warning
      receiver: 'email'

receivers:
  - name: 'default'
    webhook_configs:
      - url: 'http://webhook.example.com/alert'
  - name: 'pagerduty'
    pagerduty_configs:
      - routing_key: 'your_key_here'
  - name: 'email'
    email_configs:
      - to: 'ops@example.com'

这里有几个参数值得注意:

参数默认值说明
group_wait30s等待同类告警凑一批再发,避免碎片化
group_interval5m同一组告警的发送间隔
repeat_interval4h告警恢复前,重复通知的间隔。别设太短,否则会被骂

注意repeat_interval 设成 1h 的话,一个未恢复的告警一天会发 24 次。你想想看,值班的人会不会想打你?我一般设 4h 或 8h,既保证提醒,又不至于骚扰。

3.4 实战经验:告警规则设计的三个原则

说了这么多,最后分享三个我踩坑后总结的原则:

  1. 少即是多:不要试图监控所有指标。只监控那些“出问题必须人工介入”的场景。我曾经把磁盘 IO 的 99 分位延迟也加了告警,结果天天报警,最后发现根本没人看。
  2. 带上上下文:告警信息里一定要写清楚“影响范围”和“建议操作”。比如“CPU 高”不如“CPU 高,建议检查是否有异常进程或扩容”。
  3. 分层分级:用 severity 标签区分 critical、warning、info。Critical 走电话或 PagerDuty,warning 发邮件,info 记日志就行。

嗯,这一章的内容就到这里。告警规则和 Alertmanager 的调优其实还有很多细节,比如模板化通知、对接飞书/钉钉等。但先把基础打牢,后面再慢慢深入。


专注资料整理