7.1 告警的两段式架构
Prometheus 的告警分工明确:
- Prometheus Server:周期性评估
alerting_rules,判定哪些告警处于 firing 状态,把它们发给 Alertmanager。 - Alertmanager:接收告警,负责去重、分组、抑制、静默,最终推送到邮件/钉钉/Webhook 等渠道。
- Alerting Rule 告警规则
- 一个 PromQL 表达式 + 触发条件。表达式有结果 = 满足条件的序列进入 pending/firing。
- for 持续时间
- 条件需连续满足多久才真正 firing,用于过滤瞬时抖动。此前处于 pending 状态。
- labels 标签
- 附加到告警上,如
severity: critical,供 Alertmanager 路由与分组用。 - annotations 注解
- 人类可读的描述信息(summary/description),支持 Go 模板注入指标值。
- route 路由树
- Alertmanager 按 label 把告警匹配到不同的接收器(receiver),支持嵌套子路由。
- inhibition 抑制
- 当某高级告警触发时,自动压制相关的低级告警(如机房断网时压制单机告警)。
7.2 编写告警规则
# rules/alerts.yml
groups:
- name: host
rules:
- alert: HighCpuUsage
expr: 100 - avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100 > 85
for: 10m # 持续 10 分钟才告警
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} CPU 过高"
description: "CPU 使用率 {{ printf \"%.1f\" $value }}% 已持续 10 分钟"
- alert: InstanceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "目标 {{ $labels.instance }} 已下线"
用 promtool 测试规则
promtool check rules rules/alerts.yml 校验语法;promtool test rules test.yml 可用单元测试模拟时序断言告警是否按预期触发。
Recording Rule 记录规则
把常用的复杂查询预计算并存成新序列,加速仪表盘与告警:
- name: recording
rules:
- record: job:http_requests:rate5m
expr: sum by(job)(rate(http_requests_total[5m]))
7.3 Alertmanager 配置
# alertmanager.yml
route:
receiver: "default"
group_by: ["alertname", "cluster"]
group_wait: 30s # 首次分组等待,攒一批一起发
group_interval: 5m # 同组新告警的发送间隔
repeat_interval: 4h # 未解决告警重复提醒间隔
routes:
- match: { severity: critical }
receiver: "oncall-phone" # 严重告警走电话
- match: { team: infra }
receiver: "infra-dingtalk"
inhibit_rules: # 机房级告警时抑制单机告警
- source_matchers: ['severity="critical"']
target_matchers: ['severity="warning"']
equal: ["cluster", "instance"]
receivers:
- name: "default"
email_configs:
- to: "ops@example.com"
from: "alert@example.com"
smarthost: "smtp.example.com:587"
- name: "infra-dingtalk"
webhook_configs:
- url: "http://dingtalk-webhook:8060/dingtalk/send"
7.4 分组、抑制、静默
| 机制 | 解决的问题 |
|---|---|
| Grouping 分组 | 一次故障产生几十条告警,按 group_by 合并成一条通知,防轰炸 |
| Inhibition 抑制 | 上游故障已告警,压制被它引起的下游告警噪声 |
| Silence 静默 | 运维期间临时屏蔽指定告警(在 Alertmanager UI 里按 label 设置有效期) |
| Deduplication 去重 | 多个 Prometheus 副本发同一告警,Alertmanager 自动去重 |
Alertmanager 要做高可用
生产环境部署多个 Alertmanager 实例并用 --cluster.peer 组成集群(gossip 协议同步状态),避免单点故障漏发告警。多个 Prometheus 应同时指向所有 Alertmanager。
7.5 钉钉通知(国内常用)
# 部署 prometheus-webhook-dingtalk 作为中转
$ docker run -d -p 8060:8060 \
-v $(pwd)/dingtalk.yml:/etc/prometheus-webhook-dingtalk/config.yml \
timonwong/prometheus-webhook-dingtalk
# dingtalk.yml 配置机器人 token
targets:
webhook1:
url: https://oapi.dingtalk.com/robot/send?access_token=xxxx
secret: SECxxxx
7.6 告警设计原则
- 基于症状而非原因:告"用户请求失败率高"(症状),而非"某台机器 CPU 高"(原因之一)。
- 每条告警都可行动:收到就该有明确处理动作,否则删掉——降低告警疲劳。
- 合理分级:critical(立即处理,可电话)/ warning(工作时间处理)。
- 用 for 抗抖动:瞬时尖刺别告警,持续超阈值才告。
7.7 小结与下一步
- Prometheus 判定告警 → Alertmanager 处理通知,职责分离。
- 规则用 expr + for + labels + annotations;for 抗抖动,labels 供路由。
- Alertmanager 靠 route/group/inhibit/silence 把噪声压到可管理,且需集群化高可用。
- 下一章用 Grafana 把这些指标画成好看的仪表盘。