Prometheus告警是SRE稳定性工程的核心环节。规则设计不合理,要么告警风暴淹没值班人员,要么关键故障漏报导致业务中断。通知路由配置不当,低优先级告警频繁打扰管理层,高优先级告警却无法及时触达一线工程师。本文从规则设计方法论、分组抑制机制到多级通知路由,完整讲解生产级Prometheus告警体系的搭建过程。
Prometheus告警规则设计方法论
告警规则的核心原则:每条告警必须对应一个可执行的动作。如果收到告警后值班人员的第一反应是先观察而不采取行动,这条规则就不应该存在。遵循这个原则,从业务SLO(Service Level Objective)反向推导告警规则,而非从基础设施指标正向罗列。
以Web服务为例,SLO定义99.9%的请求在200ms内完成。据此推导出两类规则:错误率告警(5xx比例超过阈值)和延迟告警(P99延迟超过SLO)。而CPU使用率、内存利用率等基础指标只作为诊断参考,不设为告警触发条件。
groups:
- name: service_slo_alerts
rules:
- alert: HighErrorRate
expr: |
(
sum(rate(http_requests_total{code=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
) > 0.01
for: 2m
labels:
severity: critical
team: backend
annotations:
summary: "{{ $labels.service }} 5xx错误率超过1%"
description: >
当前5xx错误率 {{ $value | humanizePercentage }},
持续2分钟。SLO目标99.9%可用性。
- alert: HighLatencyP99
expr: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket[5m]))
by (le, service)
) > 0.2
for: 5m
labels:
severity: warning
team: backend
annotations:
summary: "{{ $labels.service }} P99延迟超过200ms"
for字段指定告警从条件满足到实际触发的等待时间,是减少抖动告警的关键。错误率告警设2分钟等待,因为5xx率在重启滚动更新期间可能短暂飙升。P99延迟设5分钟等待,因为慢请求可能在负载均衡切换后自行恢复。
Alertmanager分组、抑制与静默机制
告警触发后由Alertmanager处理路由。分组(Grouping)将同类型告警合并为一条通知,抑制(Inhibition)在高级别告警触发时自动静默低级别告警,静默(Silencing)用于计划内维护窗口。
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'service', 'namespace']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'default'
routes:
- match:
severity: critical
receiver: 'critical-team'
group_wait: 10s
repeat_interval: 1h
- match:
severity: warning
receiver: 'warning-team'
group_wait: 30s
repeat_interval: 4h
inhibit_rules:
- source_match:
severity: critical
target_match:
severity: warning
equal: ['service', 'namespace']
receivers:
- name: 'default'
webhook_configs:
- url: 'http://alertmanager-webhook:8080/notify'
- name: 'critical-team'
pagerduty_configs:
- routing_key: 'xxx-critical-key'
severity: critical
- name: 'warning-team'
webhook_configs:
- url: 'http://chatops-webhook:8080/warning'
group_by定义告警合并维度,同一个service下相同alertname的告警合并为一条通知。group_wait是收到第一条告警后等待多久再发送(等待更多告警加入同一组)。group_interval是已分组告警有新成员加入时的发送间隔。repeat_interval是同一告警重复通知的间隔。
inhibit_rules定义当critical级别告警触发时,相同service和namespace下的warning级别告警被自动抑制,避免告警风暴。
多级通知路由与On-Call排班集成
生产环境需要根据告警级别和时间路由到不同的通知渠道。Critical级别走PagerDuty或电话呼叫,Warning级别走企业IM,Info级别仅记录日志。结合On-Call排班系统,确保告警在正确的时间触达正确的人:
import requests
class AlertRouter:
def __init__(self, config):
self.config = config
self.oncall_api = config['oncall_api']
def route(self, alert: dict):
severity = alert.get('labels', {}).get('severity', 'warning')
service = alert.get('labels', {}).get('service', '')
team = self._get_oncall_team(service)
if severity == 'critical':
self._send_pagerduty(alert, team)
self._send_chat(alert, team, urgent=True)
elif severity == 'warning':
self._send_chat(alert, team, urgent=False)
else:
self._log_only(alert)
def _get_oncall_team(self, service: str) -> dict:
resp = requests.get(
f"{self.oncall_api}/api/v1/oncall",
params={'service': service}
)
return resp.json()
def _send_chat(self, alert, team, urgent=False):
msg = self._format_alert_msg(alert, urgent)
webhook = team.get('chat_webhook')
requests.post(webhook, json={
"msg_type": "interactive",
"card": {
"header": {
"title": msg['title'],
"template": "red" if urgent else "orange"
},
"elements": msg['elements']
}
})
AlertRouter从On-Call系统获取当前值班团队信息,根据severity决定通知渠道和紧急程度。Critical告警同时触发PagerDuty电话呼叫和IM消息,Warning告警只发IM通知,Info告警写入日志供事后审查。
告警质量治理与持续优化
告警体系上线后需要持续治理。统计每条规则的触发频率、确认率和平均响应时间,识别低质量规则。执行以下治理策略:触发频率高但确认率低的规则需要调高阈值或增加for等待时间;长期不触发的规则评估是否删除;确认后平均处理时间长的告警需要补充runbook文档。
# 告警质量看板PromQL
# 各规则7天触发次数
topk(20, sum by (alertname) (
increase(alerts_fired_total[7d])
))
# 告警抑制率
sum(increase(alerts_suppressed_total[7d]))
/
sum(increase(alerts_fired_total[7d]))
Prometheus告警体系的设计不是一次性工作,而是持续迭代的过程。从SLO出发定义规则,用分组抑制减少噪音,通过多级路由确保通知触达,定期治理提升质量,这四个环节闭环运行,才能构建出高效可靠的告警系统。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/prometheus-gao-jing-gui-ze-she-ji-yu-duo-ji-tong-zhi-lu-you/