4. SLI指标设计原则:如何选择有效的SLI
SLI(Service Level Indicator)是服务等级指标,是对服务某个维度的量化度量。选择有效的SLI是构建误差预算台账的基石。错误的SLI会导致误判服务健康状态,使SLO失去意义。本节将深入讲解如何基于四大黄金信号(延迟、错误率、吞吐量、饱和度)选择有效的SLI。
4.1 四大黄金信号概述
Google SRE团队总结出四个最能反映服务健康状况的核心信号。任何服务都可以从这四个维度进行度量,但并非每个维度都需要纳入SLO。选择哪些信号作为SLI,取决于服务的业务特性和用户预期。
| 黄金信号 | 核心关注点 | 典型SLI示例 | 适用场景 |
|---|---|---|---|
| 延迟 (Latency) | 请求处理速度 | P99响应时间 ≤ 200ms | 用户交互型服务、API网关 |
| 错误率 (Error Rate) | 请求失败比例 | HTTP 5xx占比 ≤ 0.1% | 所有在线服务 |
| 吞吐量 (Traffic/Throughput) | 请求负载量 | QPS、RPS、带宽使用率 | 容量规划、限流场景 |
| 饱和度 (Saturation) | 资源耗尽程度 | CPU使用率 ≤ 80%、队列深度 | 基础设施、数据库、中间件 |
实践要点:不要试图将所有黄金信号都定义为SLO。通常选择1-2个与用户体验最直接相关的信号作为核心SLI,其余信号作为辅助观测指标。
4.2 延迟 (Latency) — 用户体验的晴雨表
延迟衡量服务响应请求的速度。用户对延迟的感知是非线性的:100ms以内的延迟几乎无感知,500ms开始感到卡顿,超过2秒用户可能流失。因此,延迟SLI通常关注高百分位值(如P90、P99),而非平均值。
- 选择原则:优先选择尾部延迟(P99/P999)作为SLI,因为平均值会掩盖慢请求问题。
- 度量方式:使用Prometheus Histogram或Summary,定义延迟分布桶(如 ≤100ms, ≤200ms, ≤500ms, ≤1s, ≤2s)。
- 常见陷阱:仅监控服务端处理时间,忽略网络传输和客户端渲染时间。建议从客户端或负载均衡器侧采集延迟数据。
# Prometheus Histogram 示例:记录HTTP请求延迟
http_request_duration_seconds_bucket{le="0.1"} 1024
http_request_duration_seconds_bucket{le="0.2"} 2048
http_request_duration_seconds_bucket{le="0.5"} 3072
http_request_duration_seconds_bucket{le="1.0"} 3584
http_request_duration_seconds_bucket{le="+Inf"} 4096
# 计算P99延迟的PromQL
histogram_quantile(0.99,
rate(http_request_duration_seconds_bucket[5m])
)
4.3 错误率 (Error Rate) — 服务健康的直接体现
错误率是最直观的SLI。但“错误”的定义需要谨慎:并非所有HTTP 5xx都是服务端错误,也并非所有HTTP 200都是成功。例如,返回200但业务逻辑处理失败(如“用户不存在”),应视为隐式错误。
- 显式错误:HTTP 5xx、TCP连接超时、gRPC UNAVAILABLE。
- 隐式错误:HTTP 200但业务code非0、返回空数据但预期有结果、响应时间超过SLO阈值(即使状态码为200)。
- 选择原则:错误SLI必须包含显式+隐式错误的总和。仅监控5xx会遗漏大量业务故障。
# 错误率计算示例(包含显式和隐式错误)
# 假设业务指标:http_requests_total{status="200", biz_code="0"} 为成功
# 错误请求 = 总请求 - 成功请求
(
sum(rate(http_requests_total[5m]))
-
sum(rate(http_requests_total{status="200", biz_code="0"}[5m]))
)
/ sum(rate(http_requests_total[5m]))
4.4 吞吐量 (Traffic/Throughput) — 负载的度量
吞吐量衡量服务处理的请求量或数据量。虽然吞吐量本身通常不作为SLO目标(因为用户不关心QPS高低,只关心请求是否成功),但它是诊断延迟和错误率变化的关键上下文。
- 典型指标:QPS(每秒查询数)、RPS(每秒请求数)、带宽(bps)、并发连接数。
- 选择原则:吞吐量SLI主要用于容量预警和异常检测。当吞吐量突增或突降时,往往预示着问题。
- 与饱和度联动:吞吐量接近系统上限时,延迟会急剧上升。将吞吐量与饱和度结合分析,可以提前发现容量瓶颈。
案例:某电商服务在促销期间QPS从1000飙升至10000,延迟从50ms升至2s。通过吞吐量SLI的突增告警,团队提前扩容,避免了服务雪崩。
4.5 饱和度 (Saturation) — 容量瓶颈的预警
饱和度衡量服务资源被消耗的程度。当资源接近100%时,服务质量会急剧下降。饱和度SLI是预测性指标,能在延迟和错误率恶化之前发出预警。
- 常见资源:CPU、内存、磁盘I/O、网络带宽、数据库连接池、线程池队列深度。
- 选择原则:选择最稀缺或最容易成为瓶颈的资源作为饱和度SLI。例如,CPU密集型服务关注CPU使用率;I/O密集型服务关注磁盘延迟和队列长度。
- 阈值设定:不要等到100%才告警。通常设定在70%-80%作为预警阈值,90%以上为严重告警。
# 饱和度SLI示例:CPU使用率
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 数据库连接池饱和度
(avg by(service) (db_connections_in_use) / avg by(service) (db_connections_max)) * 100
4.6 四大黄金信号的关系与选择策略
四大信号并非孤立存在,它们之间存在因果关系。理解这些关系有助于选择最有效的SLI组合。
4.7 SLI选择决策矩阵
针对不同类型的服务,推荐以下SLI选择策略:
| 服务类型 | 首选SLI | 次选SLI | 辅助观测 |
|---|---|---|---|
| Web前端/API网关 | 延迟 (P99) | 错误率 | 吞吐量 |
| 数据库/缓存 | 延迟 (P50/P99) | 饱和度 (连接池/CPU) | 吞吐量 |
| 消息队列 | 延迟 (端到端) | 队列深度 (饱和度) | 吞吐量 |
| 批处理/离线任务 | 错误率 | 吞吐量 (处理速度) | 饱和度 (资源) |
| CDN/静态资源 | 延迟 (首字节时间) | 错误率 (4xx/5xx) | 带宽 (饱和度) |
避坑指南:不要将基础设施指标(如CPU使用率)直接作为用户体验的SLO。CPU 100%不一定导致用户请求失败,但P99延迟超过2秒一定会影响用户体验。始终以用户视角选择SLI。
4.8 从黄金信号到SLI的转化步骤
将黄金信号转化为可度量的SLI,需要遵循以下步骤:
- 定义用户旅程:明确用户的核心操作是什么(如登录、搜索、下单)。
- 确定关键信号:根据服务类型,从四大黄金信号中选择1-2个最相关的信号。
- 设定度量方式:确定如何采集数据(客户端埋点、服务端日志、中间件指标)。
- 定义成功标准:明确什么是“好”的指标值(如P99延迟 ≤ 200ms,错误率 ≤ 0.1%)。
- 验证相关性:通过历史数据验证SLI的波动是否与用户体验变化一致。
实战案例:某视频流服务选择“视频首帧加载时间”作为延迟SLI(P95 ≤ 1.5s),选择“播放失败率”作为错误率SLI(≤ 0.5%)。这两个SLI直接反映了用户观看体验,比服务器CPU使用率更有意义。