告警体系
概述
告警是监控体系的最后一环,决定了问题能否被及时感知和处理。一个成熟的告警体系包含告警生成 → 路由 → 抑制/分组 → 通知 → 升级完整的生命周期。
核心架构
监控数据
├── Metrics(Prometheus)
├── Logs(ELK)
└── Traces(SkyWalking)
↓
Prometheus Server
└── 根据告警规则生成 Alert
↓
AlertManager
├── 分组(Grouping):同类告警合并
├── 抑制(Inhibition):高等级告警抑制低等级
├── 静默(Silence):已知问题不重复告警
└── 通知(Notify):发送到不同渠道
↓
通知渠道
├── 企业微信 / 钉钉 / 飞书
├── 邮件 / 短信
└── PagerDuty / OpsGenie一、Prometheus 告警规则
1.1 基础告警规则
yaml
# prometheus-alert-rules.yml
groups:
- name: service_availability
rules:
# 服务宕机
- alert: ServiceDown
expr: up{job="order-service"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "{{ $labels.job }} 服务不可用"
description: "{{ $labels.instance }} 已宕机超过 1 分钟"
priority: "P0"
# 高错误率
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.05
for: 3m
labels:
severity: critical
annotations:
summary: "{{ $labels.job }} 错误率超过 5%"
description: "当前错误率:{{ $value | humanizePercentage }}"
priority: "P0"
- name: performance
rules:
# P99 响应时间过高
- alert: HighP99Latency
expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 3
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.job }} P99 响应时间超过 3s"
description: "当前 P99:{{ $value }}s"
priority: "P1"
# 慢 SQL
- alert: SlowSQL
expr: rate(database_query_duration_seconds_sum[5m]) / rate(database_query_duration_seconds_count[5m]) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "数据库查询平均耗时超过 1s"
description: "平均耗时:{{ $value }}s"
priority: "P2"
- name: resource
rules:
# CPU 使用率过高
- alert: HighCPUUsage
expr: rate(process_cpu_seconds_total[1m]) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.job }} CPU 使用率超过 80%"
description: "当前 CPU:{{ $value | humanizePercentage }}"
# GC 频繁
- alert: HighGCRate
expr: rate(jvm_gc_pause_seconds_sum[5m]) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "JVM GC 暂停时间超过 1s"
description: "GC 暂停:{{ $value }}s/5m"1.2 Java 业务指标告警
java
// 自定义业务指标
@Component
public class BusinessMetrics {
private final Counter orderCreateFailures = Metrics.counter("order.create.failures");
private final Counter paymentTimeouts = Metrics.counter("payment.timeout.total");
// 在业务代码中记录
public void recordOrderFailure(OrderRequest request, Throwable e) {
orderCreateFailures.increment();
}
}yaml
# 业务告警规则
groups:
- name: business
rules:
- alert: OrderCreateFailure
expr: rate(order_create_failures_total[5m]) > 10
for: 2m
labels:
severity: warning
annotations:
summary: "下单失败率过高"
description: "5 分钟内下单失败 {{ $value | humanizeNumber }} 次"
- alert: PaymentTimeout
expr: rate(payment_timeout_total[5m]) > 5
for: 2m
labels:
severity: critical
annotations:
summary: "支付超时率过高"
description: "5 分钟内支付超时 {{ $value | humanizeNumber }} 次"二、AlertManager 配置
2.1 基础配置
yaml
# alertmanager.yml
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.example.com:587'
smtp_from: 'alert@example.com'
smtp_auth_username: 'alert@example.com'
smtp_auth_password: 'password'
route:
receiver: 'default'
group_wait: 10s # 同组告警等待时间(收集更多告警)
group_interval: 5m # 同组告警发送间隔
repeat_interval: 4h # 重复告警间隔
group_by: ['alertname', 'job'] # 分组依据
routes:
# P0 告警 → 即时通知
- match:
severity: critical
receiver: p0-team
repeat_interval: 30m
group_wait: 5s
# P1 告警 → 工作时间通知
- match:
severity: warning
receiver: p1-team
repeat_interval: 2h
receivers:
- name: 'p0-team'
webhook_configs:
- url: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx'
send_resolved: true
email_configs:
- to: 'oncall@example.com'
- name: 'p1-team'
webhook_configs:
- url: 'https://oapi.dingtalk.com/robot/send?access_token=xxx'
send_resolved: true
inhibit_rules:
# 高等级告警抑制低等级
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['job', 'instance']2.2 分组与降噪
yaml
# 场景:100 台机器同时宕机
# 不分组:收到 100 条告警 → 告警风暴
# 分组后:收到 1 条告警 "100 instances of order-service are down"
route:
group_by: ['alertname', 'job'] # 按告警名 + 服务名分组
group_wait: 30s # 等待 30s 收集同组告警
group_interval: 5m # 5 分钟内的同组告警合并
repeat_interval: 30m # 30 分钟内不重复发送
# 通知模板
receivers:
- name: 'p0-team'
webhook_configs:
- url: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx'
send_resolved: true
# 模板消息中显示聚合后的告警数2.3 静默(Silence)
json
// AlertManager API 创建静默
// 已知问题(如计划内重启),临时静默告警
POST /api/v2/silences
{
"matchers": [
{
"name": "alertname",
"value": "ServiceDown",
"isRegex": false
},
{
"name": "job",
"value": "order-service",
"isRegex": true
}
],
"startsAt": "2026-07-24T10:00:00Z",
"endsAt": "2026-07-24T10:30:00Z",
"createdBy": "admin",
"comment": "Scheduled maintenance of order-service"
}yaml
# 配置文件方式(静默文件)
silences:
- matchers:
- name: alertname
value: ".*"
isRegex: true
- name: job
value: "batch-job"
endsAt: "2026-12-31T00:00:00Z"
comment: "已知问题,修复中"三、通知渠道
3.1 企业微信 Webhook
yaml
# AlertManager 配置
receivers:
- name: 'wechat'
webhook_configs:
- url: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxx-xxxx-xxxx-xxxx'
send_resolved: true
http_config:
headers:
Content-Type: application/jsonjson
// 企业微信消息模板
{
"msgtype": "markdown",
"markdown": {
"content": "## 🚨 告警通知\n" +
"> **告警名称:** {{ .GroupLabels.alertname }}\n" +
"> **严重级别:** {{ .CommonLabels.severity }}\n" +
"> **受影响的实例:** {{ .Alerts | len }} 个\n" +
"> **当前值:** {{ .CommonAnnotations.value }}\n" +
"> **开始时间:** {{ .StartsAt }}\n" +
"> **告警详情:** {{ .CommonAnnotations.description }}\n" +
"> **[查看告警](https://alertmanager.example.com)**"
}
}3.2 钉钉 Webhook
yaml
receivers:
- name: 'dingtalk'
webhook_configs:
- url: 'https://oapi.dingtalk.com/robot/send?access_token=xxx'
send_resolved: truejson
{
"msgtype": "markdown",
"markdown": {
"title": "告警通知",
"text": "## 🚨 告警通知\n" +
"- **告警名称:** {{ .GroupLabels.alertname }}\n" +
"- **严重级别:** {{ .CommonLabels.severity }}\n" +
"- **通知时间:** {{ .StartsAt.Format \"2006-01-02 15:04:05\" }}"
}
}3.3 邮件通知
yaml
receivers:
- name: 'email'
email_configs:
- to: 'team@example.com'
send_resolved: true
headers:
subject: '[{{ .Status | toUpper }}] {{ .GroupLabels.alertname }}'
html: |
<h2>{{ .GroupLabels.alertname }}</h2>
<table>
<tr><td>级别</td><td>{{ .CommonLabels.severity }}</td></tr>
<tr><td>服务</td><td>{{ .CommonLabels.job }}</td></tr>
<tr><td>详情</td><td>{{ .CommonAnnotations.description }}</td></tr>
<tr><td>时间</td><td>{{ .StartsAt }}</td></tr>
</table>四、SLO 驱动的告警
4.1 SLO 定义
yaml
# 服务水平目标(SLO)
#
# 可用性 SLO:99.9%(月度不可用时间 < 43 分钟)
# 延迟 SLO :P99 < 500ms(月度 99% 请求在 500ms 内)
# 燃烧率(Burn Rate):错误消耗 SLO 预算的速度
# 1x 燃烧率:按此速度,30 天消耗完 SLO 预算
# 10x 燃烧率:按此速度,3 天消耗完 SLO 预算
# 100x 燃烧率:按此速度,7 小时消耗完 SLO 预算4.2 SLO 告警规则
yaml
# SLO 告警:基于燃烧率
groups:
- name: slo_alerts
rules:
# 快速告警(高燃烧率,短窗口)
- alert: HighBurnRate
expr: |
(
rate(http_requests_total{status!~"2.."}[1h])
/
rate(http_requests_total[1h])
) > 0.001 # 1 小时内错误率 > 0.1%
for: 1m
labels:
severity: critical
annotations:
summary: "SLO 燃烧率过高"
description: "1 小时窗口错误率 {{ $value | humanizePercentage }},"
"预计 {{ humanizeDuration ($value | sloBurnRateTimeLeft 0.001) }} 内消耗完 SLO 预算"
# 慢速告警(低燃烧率,长窗口)
- alert: SlowBurnRate
expr: |
(
rate(http_requests_total{status!~"2.."}[6h])
/
rate(http_requests_total[6h])
) > 0.0005 # 6 小时内错误率 > 0.05%
for: 5m
labels:
severity: warning
annotations:
summary: "SLO 燃烧率偏高"
description: "6 小时窗口错误率 {{ $value | humanizePercentage }}"4.3 升级策略
yaml
# 告警升级(AlertManager 不支持原生升级,通过外部工具实现)
# 推荐方案:结合 FlashDuty / PagerDuty 实现升级
# 升级策略示例:
#
# 第 1 阶段(5 分钟内未确认)→ 通知值班工程师
# 第 2 阶段(15 分钟内未处理)→ 升级到团队负责人
# 第 3 阶段(30 分钟内未处理)→ 升级到部门负责人
# 第 4 阶段(1 小时内未处理)→ 通知 CTO五、告警最佳实践
5.1 告警分级
| 级别 | 定义 | 响应时间 | 通知方式 | 示例 |
|---|---|---|---|---|
| P0 | 核心服务不可用,影响用户 | 5 分钟 | 电话 + 短信 + 即时通讯 | 订单服务宕机 |
| P1 | 功能严重受损,有变通方案 | 30 分钟 | 即时通讯 | P99 > 3s |
| P2 | 非功能性告警 | 8 小时 | 邮件 | CPU > 80% |
| P3 | 信息性告警 | 24 小时 | 记录 | 证书即将过期 |
5.2 告警降噪原则
text
1. 告警要有信息量
❌ "CPU 使用率高"
✅ "order-service-3 CPU 使用率 95%(阈值 80%),持续 5 分钟"
2. 去重
❌ 100 台机器同时发 "磁盘空间不足"
✅ 1 条告警 "100 个实例磁盘使用率超过 80%"
3. 抑制
❌ 服务宕机时,同时收到 "数据库查询失败"、"HTTP 502" 等衍生告警
✅ "ServiceDown" 抑制其他衍生告警
4. 静默
❌ 计划内重启时收到告警
✅ 提前创建 Silences 静默计划内的告警
5. 避免告警疲劳
❌ 同一个告警每 5 分钟重复一次
✅ P0 每 30 分钟重复,P2 每 4 小时重复六、总结
| 知识点 | 说明 |
|---|---|
| 告警规则 | Prometheus Recording Rules + Alert Rules |
| AlertManager | 分组 / 抑制 / 静默 / 路由 |
| 通知渠道 | 企业微信 / 钉钉 / 邮件 / Webhook |
| SLO 告警 | 基于燃烧率的告警策略 |
| 告警分级 | P0-P3 四级响应 |
| 降噪 | 去重 / 抑制 / 静默 / 分组 |
| 升级策略 | 未确认自动升级到更高层级 |
参考链接: