3. SLI 采集与度量:常见类型、采集方式与度量标准
SLI(Service Level Indicator,服务等级指标)是 SLO 工程的“原材料”。没有准确、可重复的 SLI 采集与度量,SLO 就是空中楼阁。本章聚焦四大黄金信号——延迟、错误率、吞吐量、饱和度,逐一拆解其定义、采集方式与度量标准,并给出可直接落地的作业目录模板。
3.1 四大黄金信号:SLI 类型全景
Google SRE 经典理论将 SLI 归纳为四个核心维度,覆盖绝大多数后端与中间件服务。下表对比了各维度的关注点与典型场景:
| SLI 类型 | 核心关注点 | 典型服务场景 | 常见度量单位 |
|---|---|---|---|
| 延迟 (Latency) | 请求从发出到收到完整响应的时间 | API 网关、数据库查询、RPC 调用 | 毫秒 (ms)、微秒 (μs) |
| 错误率 (Error Rate) | 失败请求占总请求数的比例 | HTTP 服务、消息队列、文件上传 | 百分比 (%)、ppm |
| 吞吐量 (Throughput) | 单位时间内成功处理的请求量 | CDN 边缘、流媒体、批处理作业 | QPS、RPS、TPS、Bps |
| 饱和度 (Saturation) | 资源被占用的程度,接近瓶颈的程度 | CPU、内存、磁盘 IO、连接池 | 百分比 (%)、水位值 |
选型提示: 并非所有服务都需要同时采集四个维度。对于无状态 API 服务,延迟和错误率是必选;对于有状态存储系统,饱和度和吞吐量往往比延迟更早暴露风险。建议从“用户最直接感知”的 1-2 个维度起步,逐步扩展。
3.2 延迟 (Latency) 的采集与度量
延迟是最敏感的 SLI 之一。采集时需注意:区分客户端视角与服务端视角,并关注高百分位而非平均值。
3.2.1 采集方式
- 服务端埋点: 在请求入口与出口分别打点,计算差值。适用于 API 网关、微服务框架(如 gRPC 拦截器)。
- 客户端 RUM: 通过浏览器或移动端 SDK 采集真实用户感知的延迟,包含网络传输时间。
- 中间件代理: 如 Envoy、Nginx 的 $upstream_response_time 变量,适合 Sidecar 模式。
3.2.2 度量标准
- 百分位选择: 通常使用 p50(中位数)、p95、p99。p99 更能反映长尾问题。
- 分桶统计: 使用直方图(Histogram)而非简单平均值。例如 Prometheus 的
histogram_quantile。 - 时间窗口: 推荐 1 分钟或 5 分钟滚动窗口,避免单次抖动影响整体。
# Prometheus 延迟直方图示例(伪代码)
# 定义:请求延迟分布,桶边界为 5ms, 10ms, 25ms, 50ms, 100ms, 250ms, 500ms, 1000ms
http_request_duration_seconds_bucket{le="0.005"} 1024
http_request_duration_seconds_bucket{le="0.01"} 2048
http_request_duration_seconds_bucket{le="0.05"} 8192
# 查询 p99 延迟(过去 5 分钟)
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
3.3 错误率 (Error Rate) 的采集与度量
错误率直接反映服务可用性。定义“什么是错误”是第一步——HTTP 5xx 是错误,但 4xx 是否算错误取决于业务语义。
3.3.1 采集方式
- 状态码统计: 最直接的方式,通过负载均衡器或应用日志统计 5xx 比例。
- 业务错误码: 对于 gRPC 或自定义协议,需将业务层错误码(如超时、限流、数据校验失败)纳入统计。
- 健康检查探测: 主动探测(如 TCP 端口、HTTP 200)可补充被动采集的盲区。
3.3.2 度量标准
- 分母定义: 明确“总请求数”是否包含健康检查、爬虫、内部重试。建议只统计用户可见流量。
- 滑动窗口: 使用 1 分钟或 10 分钟滑动窗口计算错误率,避免瞬时毛刺触发告警。
- 多维度聚合: 按地域、版本、API 路径拆分,定位错误来源。
常见陷阱: 仅统计 HTTP 5xx 会遗漏“静默错误”——例如返回 200 但业务逻辑失败(如支付扣款成功但返回失败)。务必在应用层加入业务错误码 SLI。
3.4 吞吐量 (Throughput) 的采集与度量
吞吐量反映服务的处理能力。在容量规划与限流场景中,吞吐量是关键的输入指标。
3.4.1 采集方式
- 请求计数: 通过计数器(Counter)统计每秒请求数,如 Prometheus 的
rate()函数。 - 数据量统计: 对于流媒体或文件传输,使用字节数(Bytes per second)而非请求数。
- 并发连接数: 对于长连接服务(WebSocket、数据库连接池),活跃连接数比 QPS 更准确。
3.4.2 度量标准
- 峰值 vs 均值: 关注 p99 吞吐量峰值,而非 5 分钟均值。均值会掩盖突发流量。
- 饱和度关联: 吞吐量通常与饱和度配合使用——当吞吐量接近上限时,延迟会急剧上升。
3.5 饱和度 (Saturation) 的采集与度量
饱和度是“预警指标”,在系统完全过载之前发出信号。它通常不是用户直接感知的指标,但能提前 5-30 分钟预测故障。
3.5.1 采集方式
- 系统资源: CPU 使用率、内存占用、磁盘 IO 等待时间、网络带宽利用率。
- 队列深度: 请求队列长度、线程池活跃线程数、数据库连接池等待数。
- 自定义水位: 如 Kafka 消费者 Lag、消息队列积压量。
3.5.2 度量标准
- 百分比阈值: 通常设置 70% 为关注线,85% 为告警线,95% 为紧急线。
- 导数趋势: 关注饱和度的变化率(如 CPU 在 1 分钟内从 40% 升至 80%),比值更敏感。
- 关联分析: 饱和度上升 + 延迟上升 = 容量不足;饱和度上升 + 延迟不变 = 可能还有余量。
注意: 饱和度指标容易产生“噪声”。例如 CPU 使用率 100% 但服务延迟正常(如批处理任务),此时不应触发告警。建议将饱和度与延迟/错误率组合使用,避免误报。
3.6 SLI 采集架构总览
下图展示了从数据源到 SLI 度量标准的完整采集链路,涵盖四大黄金信号的采集点与聚合方式。
3.7 SLI 采集作业目录模板
以下作业目录可直接用于团队落地,每个 SLI 类型对应一个标准作业项:
| 作业编号 | SLI 类型 | 采集目标 | 采集方式 | 度量标准 | 输出产物 |
|---|---|---|---|---|---|
| SLI-01 | 延迟 | API 网关 p99 延迟 | Envoy 指标 + Prometheus Histogram | p99 ≤ 200ms(5min 窗口) | 延迟 SLI 仪表盘 |
| SLI-02 | 错误率 | HTTP 5xx 比例 | Nginx 日志 + Fluentd 聚合 | 错误率 ≤ 0.1%(1min 窗口) | 错误率告警规则 |
| SLI-03 | 吞吐量 | 核心 API QPS | 应用 Counter + rate() | 峰值 QPS ≤ 上限 80% | 容量水位报告 |
| SLI-04 | 饱和度 | 数据库连接池使用率 | JMX Exporter / 自定义 Exporter | 使用率 ≤ 75% | 饱和度预警规则 |
3.8 常见采集陷阱与避坑指南
- 陷阱 1: 只采集平均值。平均值会掩盖 1% 的慢请求,导致 SLO 虚高。必须使用百分位。
- 陷阱 2: 错误率分母不一致。健康检查、内部重试、爬虫流量会稀释错误率。建议使用标签过滤。
- 陷阱 3: 吞吐量与饱和度混淆。吞吐量是“做了多少事”,饱和度是“还能做多少事”。两者需配合使用。
- 陷阱 4: 采集频率过低。1 分钟采集一次可能错过秒级毛刺。建议至少 15 秒采集一次,聚合时再降采样。
最佳实践: 在 Prometheus 中,使用
histogram_quantile 计算延迟百分位时,确保桶边界覆盖业务预期范围(如 1ms 到 10s)。桶太少会导致百分位计算不准确,桶太多会增加存储开销。推荐 10-15 个桶。