3. Prometheus告警基础:架构、规则与Alertmanager
聊到告警,很多新手第一反应就是“配个阈值,超过就报警”。嗯,理论上没错。但实际落地时你会发现,告警系统的设计远比想象中复杂。我见过不少团队,告警配了一大堆,结果半夜全是垃圾告警,真正出问题的时候反而被淹没了。
今天这一章,我们就来拆解Prometheus告警的三大核心:架构怎么搭、规则怎么写、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 | 告警名称,必须唯一 | 命名要有规律,比如“服务名_指标名_异常类型” |
expr | PromQL 表达式,触发条件 | 尽量用 rate() 或 increase() 避免毛刺 |
for | 持续时间,防止瞬时报错 | 这个字段太重要了!我见过不加 for 的,结果网络抖动一下告警就炸了 |
labels | 附加标签,用于路由 | 建议加 severity 和 team,方便 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_wait | 30s | 等待同类告警凑一批再发,避免碎片化 |
group_interval | 5m | 同一组告警的发送间隔 |
repeat_interval | 4h | 告警恢复前,重复通知的间隔。别设太短,否则会被骂 |
注意:repeat_interval 设成 1h 的话,一个未恢复的告警一天会发 24 次。你想想看,值班的人会不会想打你?我一般设 4h 或 8h,既保证提醒,又不至于骚扰。
3.4 实战经验:告警规则设计的三个原则
说了这么多,最后分享三个我踩坑后总结的原则:
- 少即是多:不要试图监控所有指标。只监控那些“出问题必须人工介入”的场景。我曾经把磁盘 IO 的 99 分位延迟也加了告警,结果天天报警,最后发现根本没人看。
- 带上上下文:告警信息里一定要写清楚“影响范围”和“建议操作”。比如“CPU 高”不如“CPU 高,建议检查是否有异常进程或扩容”。
- 分层分级:用
severity标签区分 critical、warning、info。Critical 走电话或 PagerDuty,warning 发邮件,info 记日志就行。
嗯,这一章的内容就到这里。告警规则和 Alertmanager 的调优其实还有很多细节,比如模板化通知、对接飞书/钉钉等。但先把基础打牢,后面再慢慢深入。