Prometheus 指标设计:从 Histogram 到可执行 SLO

指标不是越多越好。有效指标应能回答用户是否受影响、问题在哪一层、是否需要立即行动。Prometheus 最容易踩的坑是 Label 基数失控,以及用平均值掩盖尾延迟。

四类指标怎么选

  • Counter:只增不减的累计量,例如请求数、错误数。
  • Gauge:可升可降的当前值,例如队列长度、在线连接。
  • Histogram:按 Bucket 记录分布,适合延迟和大小。
  • Summary:客户端计算分位数,不便跨实例聚合,使用前要明确限制。

请求指标通常使用 Counter + Histogram:

http_server_requests_total{route="/articles/:id",method="GET",code="200"}
http_server_duration_seconds_bucket{route="/articles/:id",method="GET",le="0.5"}

Route 使用模板,不能直接放真实 URL 或文章 ID。

Label 基数必须可控

不要把 user_idrequest_id、邮箱、完整错误文本作为 Label。每个不同组合都会创建新时间序列,可能耗尽 Prometheus 内存。高基数上下文放日志或 Trace,指标只保留有限枚举维度。

新增 Label 前估算:实例数 × 路由数 × 方法数 × 状态码数 × 其他维度。看似每项都不多,组合后可能快速膨胀。

Histogram Bucket 从 SLO 反推

如果目标是 95% 请求在 300ms 内、99% 在 1s 内,Bucket 边界至少要覆盖这些阈值:

0.05, 0.1, 0.2, 0.3, 0.5, 1, 2, 5

Bucket 太稀无法判断目标,太密会增加时间序列。使用真实延迟分布调整,而不是复制默认值。

计算 95 分位:

histogram_quantile(
  0.95,
  sum by (le, route) (rate(http_server_duration_seconds_bucket[5m]))
)

分位数适合观察,但 SLO 更适合直接计算“满足阈值的请求比例”,结果更稳定也更容易计算错误预算。

从 SLI 到告警

可用性 SLI:成功请求 / 有效请求。先定义哪些状态码代表系统失败,用户取消、限流和业务校验是否计入要由产品语义决定。

告警不要只写“错误率超过 1% 五分钟”。使用多窗口、多燃烧率可以同时发现快速耗尽错误预算的大故障,以及持续缓慢恶化的问题。告警必须附带 Runbook、Dashboard 和影响范围。

Recording Rule 降低查询成本

常用复杂查询预计算为 Recording Rule,Dashboard 和告警复用同一口径。规则命名体现聚合与时间窗口,并纳入代码评审和测试。修改指标 Label 时同步迁移规则,避免静默无数据。

指标上线清单

  1. 名称包含单位并符合命名规范。
  2. Label 只有有限、稳定枚举。
  3. Counter 使用 rate/increase,不直接看累计值。
  4. Histogram Bucket 覆盖业务 SLO。
  5. Dashboard、告警和 Runbook 使用同一口径。
  6. 服务下线和无流量能与采集故障区分。

参考资料