3. SLI 口径定义:什么是 SLI 口径、常见的 SLI 类型

SLI(Service Level Indicator,服务等级指标)是衡量系统某一维度服务质量的具体量化指标。在可观测性体系中,SLI 口径定义了“我们测量什么”以及“如何测量”,是构建 SLO 和错误预算的基石。如果口径定义不清晰,后续的采集、聚合、告警都将失去意义。

3.1 什么是 SLI 口径

SLI 口径包含两个核心要素:测量对象和测量方法。测量对象指被监控的实体(如 HTTP 请求、数据库查询、消息队列长度),测量方法则定义了如何从原始数据中提取指标(如统计 P99 延迟、计算 5xx 错误占比)。

一个完整的 SLI 口径通常由以下部分组成:

组成部分 说明 示例
指标名称 唯一标识该 SLI 的命名 http_request_duration_seconds
数据来源 原始数据的采集位置 API Gateway 访问日志、Agent 埋点
聚合方式 对原始数据进行统计计算的方法 平均值、百分位数(P50/P95/P99)、计数
时间窗口 指标计算的时间范围 1 分钟、5 分钟、滚动 30 天
过滤条件 排除或包含特定数据的规则 仅统计 status_code != 429 的请求
最佳实践:在 Terraform 中定义 SLI 口径时,建议将口径配置抽象为 locals 或 variable,便于在多个模块间复用。例如:locals { sli_duration_p99 = { metric = "http_request_duration_seconds", quantile = 0.99, window = "5m" } }

3.2 四大黄金 SLI 类型

业界公认的四大黄金信号(Golden Signals)对应四种核心 SLI 类型:延迟、错误率、吞吐量和饱和度。这四类指标从不同维度覆盖了用户体验和系统健康度。

四大黄金 SLI 对比矩阵

SLI 类型 测量对象 典型口径 常见阈值参考
延迟 请求响应时间 P99 延迟 < 200ms P50 < 100ms, P99 < 500ms
错误率 失败请求占比 HTTP 5xx 占比 < 0.1% 错误率 < 1% 为警戒线
吞吐量 单位时间请求量 RPS > 1000 根据业务峰值设定基线
饱和度 资源使用程度 CPU 使用率 < 80% 内存/磁盘/连接池 < 75%

3.3 延迟(Latency)

延迟衡量系统处理请求所花费的时间,是用户体验最直接的体现。延迟 SLI 通常使用百分位数而非平均值,因为平均值容易掩盖长尾问题。

  • P50(中位数):反映大多数用户的体验,适合作为日常监控基线。
  • P95 / P99:反映最差情况下的体验,是 SLO 定义中最常用的口径。
  • P999:用于对延迟极度敏感的场景(如金融交易、实时音视频)。
常见陷阱:不要使用“平均延迟”作为 SLI。例如:某系统 99% 请求耗时 10ms,但 1% 请求耗时 10s,平均延迟仅为 110ms,完全掩盖了长尾故障。始终使用百分位数。

3.4 错误率(Error Rate)

错误率衡量失败请求占总请求的比例。错误定义需要根据业务语义明确区分:

错误类型 示例 是否计入 SLI
显式错误 HTTP 5xx、超时、连接拒绝 是
隐式错误 返回 200 但业务逻辑错误(如“订单创建失败”) 建议计入
预期错误 429 限流、404 正常缺失 通常不计入

错误率口径定义示例:

# Prometheus 风格的 SLI 错误率查询
# 口径:过去 5 分钟内,HTTP 5xx 错误占总请求的比例
rate(http_requests_total{status_code=~"5.."}[5m])
/
rate(http_requests_total[5m])

3.5 吞吐量(Throughput)

吞吐量衡量系统在单位时间内处理的请求量或数据量。常见的吞吐量口径包括:

  • RPS(Requests Per Second):每秒请求数,适用于 API 网关、Web 服务。
  • TPS(Transactions Per Second):每秒事务数,适用于数据库、消息队列。
  • 吞吐字节数:每秒处理的字节量,适用于文件传输、流媒体。

吞吐量 SLI 通常与延迟和错误率配合使用:当吞吐量突然下降时,往往意味着系统正在丢弃请求或发生故障。

3.6 饱和度(Saturation)

饱和度衡量系统资源被消耗的程度,通常表示系统还能承受多少额外负载。饱和度 SLI 是预测性指标,能在系统完全过载前发出预警。

资源类型 饱和度口径 说明
CPU CPU 使用率 / CPU 运行队列长度 运行队列 > 2×CPU 核数表示过载
内存 内存使用率 / OOM 事件计数 使用率 > 90% 需关注
磁盘 I/O 磁盘队列深度 / I/O 等待时间 队列深度持续 > 磁盘并发数
网络 带宽使用率 / 丢包率 丢包率 > 0.1% 表示网络饱和
连接池 活跃连接数 / 最大连接数 活跃连接 > 80% 最大连接数
饱和度 vs 利用率:利用率是“用了多少”,饱和度是“还能用多少”。例如:CPU 利用率 70% 可能正常,但如果运行队列已经堆积,则说明 CPU 已饱和。在 Terraform 模块中,建议同时采集利用率和饱和度指标。

3.7 SLI 口径与 Terraform 模块的映射关系

在 Terraform 模块化部署中,每个 SLI 口径对应一组可重复使用的配置资源。下图展示了 SLI 口径定义如何映射到 Terraform 模块的输入变量和输出指标:

SLI 口径 → Terraform 模块映射关系 SLI 口径定义层 延迟 P99 < 200ms 错误率 < 0.1% 吞吐量 > 1000 RPS CPU 饱和度 < 80% 映射 Terraform 模块实现层 module "sli_latency" { source = "./modules/sli" metric_type = "latency" quantile = 0.99 module "sli_error_rate" { source = "./modules/sli" metric_type = "error_rate" error_codes = ["5xx"] module "sli_throughput" { source = "./modules/sli" metric_type = "throughput" unit = "rps" module "sli_saturation" { source = "./modules/sli" metric_type = "saturation" resource = "cpu" }

3.8 选择 SLI 口径的实用原则

  1. 用户视角优先:选择能直接反映用户体验的指标,而非内部实现细节。例如:用“页面加载时间”而非“数据库查询时间”。
  2. 可测量性:确保口径对应的原始数据能够稳定采集,避免依赖实验性或高成本的采集方式。
  3. 可操作性:每个 SLI 口径都应该能触发明确的运维动作。如果某个指标下降后团队不知道如何响应,则不应作为 SLI。
  4. 避免指标膨胀:每个服务建议定义 3~5 个核心 SLI,过多的 SLI 会导致监控疲劳和告警风暴。

Terraform 模块化建议:在 Terraform 中定义 SLI 口径时,建议使用 for_each 或 count 批量创建同类 SLI 资源。例如:

# 批量创建延迟 SLI 模块
variable "latency_slis" {
  type = map(object({
    quantile  = number
    threshold = number
    window    = string
  }))
  default = {
    p50 = { quantile = 0.50, threshold = 100, window = "5m" }
    p95 = { quantile = 0.95, threshold = 300, window = "5m" }
    p99 = { quantile = 0.99, threshold = 500, window = "5m" }
  }
}

module "latency_sli" {
  for_each = var.latency_slis
  source   = "./modules/sli"
  metric   = "http_request_duration_seconds"
  type     = "latency"
  quantile = each.value.quantile
  threshold = each.value.threshold
  window    = each.value.window
}