Prometheus Alert 设计师
设计 Prometheus 告警规则,以确保只有重要的事件才会触发告警。分析 PromQL 查询的正确性,根据实际流量模式设置阈值,创建性能记录规则,并实现多窗口烧率 SLO 告警 —— 生产环境告警的金标准。
使用场景:创建 Prometheus 告警、告警太吵闹、设计告警规则、编写 PromQL 监控、设置 SLO 基础告警、审查告警规则或配置 Alertmanager 路由。
核心理念
告警的三大法则:
每个告警必须是可执行的 —— 如果没有人需要采取行动,删除它。
每个告警必须是紧急的 —— 如果可以等到周一, 那就不是告警(而是票)。
每个告警必须是真实的 —— 如果它触发,但服务正常,告警是有问题的。
分析步骤
查询 Prometheus API 列出所有规则、当前触发的告警和告警历史。对于每个告警,评估:
触发频率高(>3 次/周)?可能太敏感。
没有人在触发时采取行动?删除或降级。
触发并在 <5 分钟内自动解决?抖动。
阈值基于数据还是猜测?大多数是猜测。
有 runbook 链接?没有的话,在 3 点钟是无用的。
服务可用性告警
高错误率:
间隔:30 秒
规则:
表达式:(sum(rate(http_requests_total{status=~"5.."}[5m])) by (job, service) / sum(rate(http_requests_total[5m])) by (job, service))
100 > 5
for:5 分钟
标签:严重性:critical 团队:"{{ $labels.service }}"
注释:摘要:"{{ $labels.service }}" 的高错误率
描述:错误率是 {{ printf "%.2f" $value }}%(阈值:5%)。
服务:{{ $labels.service }}
作业:{{ $labels.job }}
runbook_url: "https://wiki.internal/runbooks/high-error-rate"
dashboard_url: "https://grafana.internal/d/svc-overview?var-service={{ $labels.service }}"关键设计决策:
for:5 分钟防止对暂时性峰值进行告警(单次重试风暴)
rate()[5m] 平滑 5 分钟 —— 更短的窗口更吵闹
按服务分组,以便每个服务都有自己的告警实例
同时包含摘要(用于 pager)和描述(用于上下文)
始终包含 runbook_url 和 dashboard_url
服务宕机(无流量):
表达式:up{job="my-service"} == 0 或 absent(up{job="my-service"})
for:2 分钟
标签:严重性:page
注释:摘要:"{{ $labels.job }}" 在 "{{ $labels.instance }}" 上宕机
描述:目标已无法访问 2 分钟。重要:使用 absent() 来捕获目标完全消失的情况(Prometheus 停止抓取它,因此 up 返回无数据而不是 0)。
延迟告警
高延迟(基于直方图):
表达式:histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))> 2.0
for:10 分钟
标签:严重性:警告
注释:摘要:"{{ $labels.service }}" 的 P99 延迟超过 2 秒
描述:P99 延迟是 {{ printf "%.2f" $value }} 秒延迟规则:
始终使用 histogram_quantile,告警 P99 而不是 P50,使用 for:10 分钟,根据 SLO 设置阈值。
饱和告警
磁盘空间 —— 使用 predict_linear 代替静态阈值:
表达式:predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}[6h], 243600) < 0
for:30 分钟
标签:严重性:警告
注释:摘要:"{{ $labels.instance }}" 的磁盘将在 24 小时内填满
predict_linear 捕获磁盘在 60% 时以每小时 5% 的速度增长(8 小时内将出现问题),同时忽略磁盘在 85% 时使用率稳定的情况。
CPU/内存 —— 同样的模式:
1 - avg(rate(node_cpu_seconds_total{mode="idle"}[10m])) by (instance) 100 > 85 用于 CPU,
1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) 100 > 90 用于内存。
使用 for:10 分钟以避免暂时性峰值。
记录规则预计算昂贵的查询,以便仪表板加载快速,告警评估可靠。
何时创建记录规则:
查询使用 rate() + 跨多个系列(>1000 个时间序列)的聚合
相同的查询出现在多个告警或仪表板中
查询需要 >2 秒才能评估
查询用于 SLO 计算
命名约定:
level:metric:operations
groups:
间隔:30 秒
规则:
- 记录:服务:http_requests_total:rate5m
表达式:sum(rate(http_requests_total[5m])) by (service)
- 记录:服务:http_requests_errors:rate5m
表达式:sum(rate(http_requests_total[5m])) by (service)