3. SLI 指标设计:如何为不同服务定义有效的 SLI 指标

SLI(Service Level Indicator)是 SLO 体系的基石。没有精确、可采集的 SLI,SLO 就是空中楼阁。本章聚焦于如何为不同服务类型定义有效的 SLI 指标,覆盖延迟、错误率、吞吐量、饱和度四个黄金信号,并提供从理论到落地的完整设计方法。

核心原则:SLI 必须满足“可测量、可对比、可告警”三要素。每个 SLI 都应明确采集窗口、聚合方式与良好事件判定标准。

3.1 四大黄金信号与 SLI 映射

Google SRE 经典理论将服务监控指标归纳为四个黄金信号。每个信号对应一类典型的 SLI 定义方式:

黄金信号 典型 SLI 定义 适用场景 常见采集粒度
延迟 请求在指定阈值内完成的百分比 API、数据库、缓存、RPC 调用 p50/p95/p99,窗口 1min-5min
错误率 请求返回非成功状态码的占比 HTTP 服务、gRPC、消息队列消费 5xx 占比、业务错误码占比
吞吐量 单位时间内成功处理的请求量 网关、批处理、流处理系统 QPS、TPS、RPS
饱和度 资源使用量占总容量的比例 CPU、内存、磁盘、连接池、队列深度 利用率百分比、队列长度
设计提示:不要试图为每个信号都定义 SLI。优先选择与用户体验最直接相关的 1-2 个信号。例如,用户侧 API 优先关注延迟和错误率;后台批处理优先关注吞吐量和饱和度。

3.2 延迟 SLI:从分布到阈值

延迟 SLI 的核心是“在给定时间窗口内,请求延迟低于目标阈值的比例”。定义时需明确三个参数:

  • 采集窗口:通常为 1 分钟或 5 分钟滑动窗口,避免毛刺导致误告警。
  • 聚合方式:推荐使用百分位数(p50/p95/p99),而非平均值。平均值会掩盖长尾延迟。
  • 良好事件判定:延迟 ≤ 阈值(如 p99 ≤ 200ms)视为一次良好事件。
# 延迟 SLI 示例(PromQL 风格)
# 计算过去 5 分钟内,p99 延迟 ≤ 200ms 的请求占比
(
  sum(rate(http_request_duration_seconds_bucket{le="0.2"}[5m]))
  /
  sum(rate(http_request_duration_seconds_count[5m]))
) * 100
常见陷阱:仅使用 p50 作为延迟 SLI 会导致大量慢请求被忽略。建议至少同时跟踪 p95 和 p99,并针对 p99 设置告警阈值。

3.3 错误率 SLI:区分显式与隐式错误

错误率 SLI 定义为“错误请求数 / 总请求数 × 100%”。但“错误”的定义需要精细设计:

错误类型 示例 是否计入 SLI 说明
HTTP 5xx 500 Internal Server Error 是 服务端故障,直接影响用户
HTTP 4xx 404 Not Found 否(通常) 客户端错误,非服务责任
业务错误码 订单超时、库存不足 视情况 需业务方定义“可接受错误”
超时/熔断 上游调用超时 是 属于服务能力不足
# 错误率 SLI 示例(仅计算 5xx)
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
最佳实践:对于业务服务,建议定义“有效错误率”——排除已知的客户端错误(如 4xx)和计划内的业务拒绝(如限流返回 429),只统计真正反映服务健康度的错误。

3.4 吞吐量 SLI:容量与负载的平衡

吞吐量 SLI 通常定义为“单位时间内成功处理的请求数”。它本身不直接反映服务质量,但结合延迟和错误率可以判断服务是否过载。

  • 吞吐量:QPS / TPS,用于衡量系统处理能力。
  • 相对吞吐量:当前吞吐量 / 历史峰值吞吐量,用于判断是否接近容量上限。
  • 吞吐量异常:当吞吐量突然下降 50% 以上时,通常意味着服务故障或上游限流。
设计建议:吞吐量 SLI 更适合作为“辅助指标”而非核心 SLO。例如,当吞吐量下降且错误率上升时,触发告警自愈流程。

3.5 饱和度 SLI:资源瓶颈的早期预警

饱和度 SLI 关注资源使用量占总容量的比例。它是四个信号中唯一一个“预测性”指标,能在故障发生前发出预警。

资源类型 典型 SLI 定义 告警阈值建议 说明
CPU CPU 利用率(1min 平均) ≥ 80% 超过 80% 可能引发延迟抖动
内存 内存使用率 ≥ 85% 接近 OOM 风险
磁盘 I/O 磁盘队列深度 / 最大队列深度 ≥ 70% I/O 等待时间会急剧上升
连接池 活跃连接数 / 最大连接数 ≥ 80% 新连接可能被阻塞
消息队列 队列积压消息数 ≥ 1000(视业务定) 消费能力不足
# 饱和度 SLI 示例(CPU 利用率)
avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))
# 转换为利用率:1 - 上述值

3.6 SLI 设计流程:从服务类型到指标定义

不同服务类型需要不同的 SLI 设计策略。以下是一个通用的四步设计流程:

  1. 识别用户旅程:确定服务对外提供的核心功能(如“用户登录”、“商品搜索”)。
  2. 选择黄金信号:根据服务类型选择 1-2 个最相关的信号(如 API 选延迟+错误率,缓存选延迟+饱和度)。
  3. 定义良好事件:明确“什么算一次好的请求”(如 p99 延迟 ≤ 200ms 且状态码 200)。
  4. 设定采集与聚合:确定指标来源(APM、Exporter、业务埋点)、窗口大小、百分位选择。
SLI 设计四步流程 ① 识别用户旅程 ② 选择黄金信号 ③ 定义良好事件 ④ 设定采集与聚合 输出:每个服务 1-2 个核心 SLI,附带采集方式与良好事件判定标准 示例:API 服务 → 延迟 SLI(p99 ≤ 200ms)+ 错误率 SLI(5xx 占比 ≤ 1%)

3.7 不同服务类型的 SLI 设计模板

以下模板可直接用于常见服务类型的 SLI 定义:

服务类型 推荐 SLI 良好事件定义 采集方式
HTTP API 网关 延迟 + 错误率 p99 ≤ 300ms 且 5xx 占比 ≤ 0.5% APM 或反向代理日志
数据库(MySQL/Redis) 延迟 + 饱和度 p99 查询延迟 ≤ 50ms,连接数 ≤ 80% 数据库 Exporter
消息队列(Kafka/RabbitMQ) 吞吐量 + 饱和度 消费速率 ≥ 生产速率 90%,队列积压 ≤ 1000 MQ Exporter + 业务埋点
批处理任务 吞吐量 + 错误率 任务完成率 ≥ 99%,失败重试次数 ≤ 3 任务调度系统指标
CDN / 静态资源 延迟 + 错误率 全球 p95 延迟 ≤ 100ms,命中率 ≥ 95% CDN 厂商 API
快速上手:如果团队刚开始建设 SLI,建议从“HTTP API 延迟 + 错误率”开始,这是最容易采集且与用户体验最直接相关的指标。后续再逐步扩展到基础设施饱和度。

3.8 SLI 与 SLO 的衔接:从指标到目标

定义好 SLI 后,下一步是设定 SLO 目标值。SLI 是“测量值”,SLO 是“目标值”。例如:

  • SLI:过去 5 分钟内,p99 延迟 ≤ 200ms 的请求占比。
  • SLO:该占比 ≥ 99.9%(即每月允许的坏事件窗口约 43 分钟)。

SLI 的采集窗口和聚合方式直接影响 SLO 的达成判断。建议在定义 SLI 时就明确:

  • 窗口大小:推荐 5 分钟滑动窗口,平衡灵敏度与稳定性。
  • 百分位选择:核心服务用 p99,非核心服务可用 p95。
  • 排除策略:是否排除计划内维护、客户端错误等。
SLI 到 SLO 映射关系 SLI(指标) p99 延迟 ≤ 200ms 的请求占比 设定阈值 ≥ 99.9% SLO(目标) 每月坏事件窗口 ≤ 43 分钟 SLI 是测量值,SLO 是目标值。SLI 的采集方式决定了 SLO 的可达成性。
关键提醒:SLI 定义完成后,必须经过“可采集性验证”——确认指标能从现有监控系统(Prometheus、Datadog、SkyWalking 等)中稳定获取。如果无法采集,再完美的 SLI 定义也是无效的。