3. SLI指标设计原则

在 SLO 体系中,SLI(Service Level Indicator)是衡量服务质量的具体量化指标。选择错误的 SLI 会导致 SLO 失去意义,甚至误导优化方向。本节围绕 RED 方法(Rate、Errors、Duration)展开,讲解如何为不同服务层选择正确的黄金信号指标。

3.1 RED 方法:三大黄金信号

RED 方法由 Google SRE 团队提出,将服务监控指标简化为三个核心维度,覆盖用户可感知的服务质量全貌:

维度 指标名称 含义 典型 PromQL 示例
Rate 请求速率 单位时间内服务接收的请求总数 rate(http_requests_total[5m])
Errors 错误率 失败请求占总请求的比例 rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])
Duration 响应延迟 请求处理耗时分布,通常取 p50/p95/p99 histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
实践要点:RED 指标必须从用户视角采集。例如,对于 API 网关,Rate 是客户端发起的请求数,而非后端内部重试次数;Errors 应包含 HTTP 5xx 和业务逻辑错误码(如 200 但 body 含 error 字段)。

3.2 SLI 设计原则:从 RED 到黄金信号

选择 SLI 时需遵循以下四项原则,确保指标可测量、可对比、可行动:

  1. 用户相关:指标必须反映用户真实体验,而非内部系统健康度。例如,数据库连接池空闲数不是 SLI,但查询延迟是。
  2. 可测量:指标必须能被 Prometheus 等工具稳定采集,且具有明确的计数/分布语义。
  3. 可对比:同一指标在不同时间、版本、集群间应保持一致的采集方式和标签结构。
  4. 可行动:当 SLI 偏离阈值时,团队能通过告警定位到具体组件或代码变更。
避坑提醒:不要将基础设施指标(如 CPU 使用率、内存占用)直接作为 SLI。这些指标与用户体验之间通常存在间接关系,容易产生误报。正确的做法是将基础设施指标作为故障根因分析的辅助数据,而非 SLO 计算依据。

3.3 不同服务层的 RED 指标选择矩阵

不同服务类型对 RED 指标的侧重点不同。下表给出常见服务层的推荐 SLI 组合:

服务类型 Rate Errors Duration 说明
HTTP API / 网关 请求数/秒 5xx 比例 + 业务错误码比例 p99 延迟 最经典的 RED 应用场景
gRPC 服务 RPC 调用数/秒 非 OK 状态码比例 p99 延迟(按 method 拆分) 注意区分 UNAVAILABLE 与 INTERNAL
消息队列消费者 消息处理数/秒 处理失败 + 重试次数 端到端处理延迟(p95) Rate 需区分生产与消费速率
数据库查询 查询数/秒 超时 + 错误查询比例 p99 查询延迟 需按查询类型(读/写)拆分
批处理作业 作业完成数/时间窗口 失败作业比例 作业完成时长(p95) Rate 通常按天或小时聚合

3.4 黄金信号与 SLI 的映射关系

下图展示 RED 三大黄金信号如何映射到具体的 Prometheus 指标类型和 SLO 目标:

RED 黄金信号 → SLI 指标映射 Rate 请求速率 请求数 / 秒 Errors 错误率 失败请求比例 Duration 延迟 p50 / p95 / p99 Counter 计数器 Counter + Gauge Histogram 直方图 SLO: 请求量 ≥ 阈值 容量规划依据 SLO: 错误率 ≤ 0.1% 错误预算消耗 SLO: p99 ≤ 200ms 性能优化目标 核心原则:每个黄金信号至少对应一个 Prometheus 指标类型,并直接关联到 SLO 目标 避免使用 Gauge 直接作为 SLI(如内存使用率),优先选择 Counter 和 Histogram

3.5 实战案例:为订单服务定义 SLI

假设我们有一个订单创建服务(HTTP API),需要为其定义 SLI。按照 RED 方法,推荐指标如下:

# 1. Rate:每秒订单创建请求数
rate(order_create_requests_total[5m])

# 2. Errors:HTTP 5xx 错误率 + 业务错误率(如库存不足)
rate(order_create_requests_total{status=~"5.."}[5m]) / rate(order_create_requests_total[5m])

# 3. Duration:订单创建接口 p99 延迟
histogram_quantile(0.99, rate(order_create_duration_seconds_bucket[5m]))
关键决策:对于 Errors 指标,必须明确“什么是错误”。在订单服务中,HTTP 200 但返回“库存不足”也应计入错误率,因为这对用户而言是失败体验。建议在应用层通过自定义 metric(如 order_create_errors_total{reason="out_of_stock"})记录业务错误。

3.6 避免常见的 SLI 设计陷阱

  • 陷阱一:使用平均值代替分位数。平均延迟会掩盖长尾请求,必须使用 p95/p99 分位数。
  • 陷阱二:忽略 Rate 的归一化。不同时间窗口的 Rate 值不可直接对比,统一使用 5m 或 10m 窗口。
  • 陷阱三:Errors 只统计 HTTP 5xx。业务错误(如 4xx 中的 429 限流、200 中的业务失败)同样消耗错误预算。
  • 陷阱四:Duration 指标未按维度拆分。不同 API 路径、不同用户类型的延迟差异可能很大,需按 endpoint、method 等标签拆分。

通过遵循 RED 方法和上述原则,你可以为任何服务层设计出可测量、可对比、可行动的 SLI 指标,为后续的 SLO 定义和性能调优打下坚实基础。