3. SLI 指标设计原则:如何选择有效的 SLI

SLI(Service Level Indicator)是 SLO 的量化基础。选错 SLI,再复杂的异常检测也无法准确反映真实服务质量。本章聚焦黄金信号(Golden Signals)与 USE/RED 方法,给出可落地的 SLI 选择原则。

3.1 黄金信号:四大核心维度

Google SRE 团队提出的“黄金信号”是 SLI 设计的起点,涵盖延迟、错误率、吞吐量和饱和度。四个维度缺一不可,但并非每个服务都需要全部覆盖——应根据服务类型(在线、批处理、存储)裁剪。

维度 定义 典型 SLI 示例 采集来源(OTel)
延迟 请求从发出到收到响应的时间 p50 / p95 / p99 延迟 ≤ 200ms http.server.duration / rpc.server.duration
错误率 失败请求占总请求的比例 HTTP 5xx 占比 ≤ 1% http.server.request_count (status_code)
吞吐量 系统每秒处理的请求数 QPS ≥ 1000 http.server.request_count (rate)
饱和度 资源使用程度,越接近上限越危险 CPU 使用率 ≤ 80% process.runtime.jvm.cpu.utilization / system.cpu.utilization
实践建议: 不要将四个信号全部设为 SLI。对于用户感知型服务,优先选择延迟和错误率;对于基础设施层,优先选择饱和度和吞吐量。

3.2 USE 方法:面向资源

USE(Utilization、Saturation、Errors)由 Brendan Gregg 提出,适用于硬件资源(CPU、内存、磁盘、网络)的可观测性。每个资源都从三个角度评估:

  • 利用率(Utilization):资源被占用的平均比例。例如 CPU 利用率 70%,磁盘 I/O 利用率 60%。
  • 饱和度(Saturation):资源排队或过载的程度。例如 CPU 运行队列长度、磁盘 I/O 等待队列。
  • 错误(Errors):资源层面的错误计数。例如磁盘坏道、网络丢包、内存 ECC 错误。
USE 方法适用场景: 数据库节点、缓存集群、负载均衡器、物理机/虚拟机。不适合直接用于业务 API 或用户界面。

3.3 RED 方法:面向服务

RED(Rate、Errors、Duration)由 Tom Wilkie 提出,专为微服务和 API 设计。它将黄金信号简化为三个指标:

  • 速率(Rate):每秒请求数(RPS),对应吞吐量。
  • 错误(Errors):失败请求的比例或数。
  • 持续时间(Duration):请求处理时间分布,对应延迟。

RED 方法省略了饱和度,因为服务层面的饱和度通常由下游资源(数据库、网络)体现,更适合在 USE 中处理。

对比维度 USE 方法 RED 方法
目标对象 基础设施资源 微服务 / API
核心指标 利用率、饱和度、错误 速率、错误、持续时间
典型 SLI CPU 利用率、磁盘队列长度 QPS、错误率、p99 延迟
与 OTel 集成 system.* / process.* metrics http.* / rpc.* metrics
异常检测重点 资源瓶颈预测 用户体验退化
SLI 选择方法:USE vs RED USE 方法(面向资源) 利用率 饱和度 错误 CPU / 内存 / 磁盘 / 网络 system.* / process.* metrics 异常检测:资源瓶颈预测 RED 方法(面向服务) 速率 错误 持续时间 微服务 / API / 网关 http.* / rpc.* metrics 异常检测:用户体验退化 互补

3.4 SLI 选择原则:五条硬规则

  1. 用户视角优先:SLI 必须反映用户真实体验。例如,选择“页面加载时间”而非“服务器处理时间”。
  2. 可测量且可采集:SLI 必须能从 OTel 指标、日志或链路中稳定获取,避免依赖手工上报。
  3. 区分“好”与“坏”:每个 SLI 必须有明确的阈值或分布边界。例如“p99 延迟 ≤ 500ms”比“平均延迟”更有意义。
  4. 避免指标爆炸:每个服务选择 3~5 个 SLI 即可。过多 SLI 会导致 SLO 碎片化,异常检测噪声增大。
  5. 分层覆盖:基础设施层用 USE,服务层用 RED,业务层用黄金信号裁剪版。三层之间通过 OTel 的 Resource 属性关联。
常见陷阱: 不要将“CPU 利用率”直接作为用户请求的 SLI。CPU 高不一定代表用户体验差,可能是后台批处理任务导致。始终从用户请求链路出发选择 SLI。

3.5 从 SLI 到 SLO:阈值与分布

选定 SLI 后,需要定义“好事件”的标准。以延迟为例:

# OpenTelemetry 指标定义示例(Prometheus 格式)
# 延迟 SLI:http.server.duration
# 好事件:p99 延迟 < 200ms
# 坏事件:p99 延迟 >= 200ms

# 在 OTel Collector 中配置 Service Level Indicator
processors:
  filter/sli:
    metrics:
      include:
        match_type: regexp
        metric_names:
          - http.server.duration
  transform/sli:
    metric_statements:
      - context: datapoint
        statements:
          - set(attributes["sli_type"], "latency")
          - set(attributes["good"], gauge < 200000)  # 200ms = 200000µs

上述配置将延迟数据标记为“好”或“坏”,后续 SLO 计算和异常检测直接基于此标签聚合。

3.6 实战:为电商下单服务选择 SLI

层级 方法 SLI 好事件标准 OTel 指标
API 网关 RED 下单请求延迟 p95 ≤ 500ms http.server.duration
订单服务 RED 下单错误率 HTTP 5xx < 0.5% http.server.request_count
数据库 USE 连接池饱和度 活跃连接 < 80% 最大连接 db.client.connections.usage
缓存 USE 缓存命中率 命中率 ≥ 90% cache.hit.ratio
关键结论: SLI 设计不是一次性工作。随着服务演进,SLI 需要定期复审。建议每季度结合 SLO 达成率和异常检测告警质量,调整 SLI 的阈值和分布边界。