跳到主要内容

告警策略与On-Call实践

1. 告警分级

级别含义响应时间通知方式
P0 Critical服务不可用、数据丢失5 分钟内电话 + 短信 + 群
P1 High严重降级、部分不可用15 分钟内短信 + 群
P2 Warning性能下降、资源预警1 小时内IM 群
P3 Info信息性、趋势异常工作时间邮件

2. 好告警的特征

  • 可执行:收到告警知道做什么(有 runbook 链接)
  • 有意义:反映真实用户影响
  • 不重复:同一问题不连续报
  • 有上下文:含 namespace / pod / url / 当前值

反面:告警疲劳 = 大量无意义告警 → 全员屏蔽 → 真出事没人看。

3. 核心告警规则

3.1 可用性

- alert: ServiceDown
expr: up{job="frontend"} == 0
for: 1m
labels: { severity: critical }
annotations:
summary: "}} $labels.instance }} 下线"
runbook: "https://wiki/runbooks/service-down"

3.2 错误率

- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{status=~"5..", namespace="frontend"}[5m]))
/ sum(rate(http_requests_total{namespace="frontend"}[5m])) > 0.01
for: 5m
labels: { severity: warning }

3.3 延迟

- alert: HighP95Latency
expr: |
histogram_quantile(0.95, sum by (le) (
rate(http_request_duration_seconds_bucket{namespace="frontend"}[5m])
)) > 2
for: 10m

3.4 资源

- alert: HighMemory
expr: |
container_memory_working_set_bytes{namespace="frontend"}
/ container_spec_memory_limit_bytes > 0.85
for: 5m

- alert: DiskAlmostFull
expr: |
(node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.15
for: 10m

3.5 证书过期

- alert: CertExpiring
expr: probe_ssl_earliest_cert_expiry - time() < 30 * 86400
for: 1h
labels: { severity: warning }

4. Alertmanager 路由

route:
receiver: default
group_by: [alertname, namespace]
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- matchers: [severity="critical"]
receiver: pager
repeat_interval: 15m
- matchers: [severity="warning", team="frontend"]
receiver: frontend-channel
- matchers: [alertname="Watchdog"]
receiver: /dev/null

receivers:
- name: pager
pagerduty_configs:
- service_key: '<key>'
webhook_configs:
- url: 'https://hooks.feishu.cn/...'

- name: frontend-channel
slack_configs:
- api_url: 'https://hooks.slack.com/...'
channel: '#frontend-alerts'
title: '&#125;&#125; .GroupLabels.alertname &#125;&#125;'
text: '&#125;&#125; range .Alerts &#125;&#125;&#125;&#125; .Annotations.summary &#125;&#125;\n&#125;&#125; end &#125;&#125;'

inhibit_rules:
- source_matchers: [severity="critical"]
target_matchers: [severity="warning"]
equal: [alertname, namespace]

inhibit_rules:critical 触发时抑制同名 warning(减少噪声)。

5. On-Call 轮值

5.1 工具

工具特点
PagerDuty最成熟,贵
OpsGenie(Atlassian)集成 Jira
Grafana OnCall(开源)免费自建
飞书/钉钉值班机器人国内轻量

5.2 排班

  • 周轮:每人一周(7×24 不现实,跨时区分)
  • 主 / 副:主值班处理,副兜底
  • 升级策略:5 分钟主不响应 → 自动转副 → 10 分钟无响应 → leader

5.3 值班职责

  • 响应:收到告警 5 分钟内确认
  • 定级:判断 P0-P3
  • 处置:能解决就解决,不能升级
  • 沟通:影响用户的实时更新状态(内部群 / 状态页)
  • 复盘:重大事故写 postmortem

6. Postmortem(事后复盘)

## 事故报告 #42

### 概况
- 时间:2026-06-18 14:00 - 14:35 (35 分钟)
- 影响:前端 API 返回 502,约 5000 用户受影响
- 级别:P1

### 时间线
- 14:00 发布新版本
- 14:02 502 告警触发
- 14:05 值班人员确认
- 14:10 定位根因:新版本 DB 查询死锁
- 14:15 执行回滚
- 14:20 回滚完成,502 率下降
- 14:35 全部恢复

### 根因
新版本引入的复杂查询在并发场景下导致 DB 行锁升级为表锁。

### 教训
1. 复杂查询上线前必须压测
2. DB 慢查询监控阈值从 5s 降到 2s
3. 灰度比例从 10% 开始而非直接全量

### Action Items
- [ ] 加 DB 死锁告警 @Bob 本周
- [ ] CI 加 SQL review @Alice 本周
- [ ] 灰度流程写入规范 @Team Lead 下周

无责文化:关注系统改进而非追责。

7. 状态页

对外公示服务状态:

维护中 / 部分故障 / 重大故障 → 用户自查不用反复问客服。

8. 常见反模式

  • 所有告警 critical:on-call 全屏蔽
  • 告警没 runbook:值班人员不知道怎么处理
  • repeat_interval 太短:同一问题每 5 分钟发一次
  • 不做 inhibit:critical + warning 同时报
  • 值班没补偿:半夜被叫没调休,团队抵触
  • postmortem 追责:以后人人隐瞒
  • 告警发到大群:没人觉得自己该处理
  • 不做值班交接:上手的人不知道当前未解决的问题

9. 延伸阅读