3. SLI 口径设计原则:明确性、可重复性、可自动化、面向用户

SLI(Service Level Indicator,服务等级指标)口径是 SRE 可观测性体系的基石。一个定义模糊、无法复现或依赖人工操作的 SLI,不仅无法准确反映服务健康状态,还会在故障排查和容量规划中引入噪声。本章围绕四项核心原则展开,确保 SLI 口径在 IaC 环境中具备工程级可靠性。

3.1 明确性:消除歧义,精确到原子操作

明确性要求 SLI 口径的每个构成要素——数据源、采集方式、聚合窗口、成功/失败判定——都具备唯一且无歧义的定义。模糊的口径会导致不同团队对同一指标产生不同解读,破坏 SLO 的契约效力。

要素 模糊定义(反例) 明确定义(正例)
数据源 从负载均衡获取请求日志 从 ALB 访问日志(S3 路径:s3://prod-alb-logs/AWSLogs/)提取 elb_status_code 字段
成功判定 请求成功返回 elb_status_code 在 [200, 299] 范围内,且 request_processing_time < 500ms
聚合窗口 统计过去 5 分钟的成功率 以 1 分钟为粒度,滑动窗口 5 分钟,计算 sum(成功请求) / sum(总请求)
实践要点: 在 IaC 仓库中为每个 SLI 维护一个 YAML 定义文件,字段包括 name、datasource、filter、success_condition、window、aggregation。通过代码评审确保定义无歧义。

3.2 可重复性:相同输入必然产生相同输出

可重复性保证 SLI 口径不依赖环境上下文、时间偏移或人工操作。当两个工程师在相同时间窗口内对同一数据源执行口径查询时,必须得到完全一致的结果。这是 SLI 作为可审计契约的基础。

  • 确定性查询: 避免使用 NOW()、RAND() 等非确定性函数;使用固定时间戳或参数化时间窗口。
  • 幂等性: 同一口径重复执行多次,结果不变(不考虑数据自然增长)。
  • 版本锁定: 口径定义、查询脚本、依赖库版本均纳入 IaC 版本控制。
# 可重复性反例:依赖系统时间
SELECT COUNT(*) AS total
FROM requests
WHERE timestamp > NOW() - INTERVAL '5 minutes';

# 可重复性正例:使用参数化时间窗口
-- :start_time 和 :end_time 由编排层传入固定值
SELECT COUNT(*) AS total
FROM requests
WHERE timestamp >= :start_time AND timestamp < :end_time;
IaC 实践: 将 SLI 查询封装为 Terraform 或 Pulumi 中的 data 资源,每次执行时传入相同的 start_time 和 end_time 参数,确保 CI/CD 流水线中的每次评估结果可复现。

3.3 可自动化:从采集到告警全链路无人值守

可自动化原则要求 SLI 口径的采集、计算、存储、告警全流程无需人工介入。在 IaC 环境中,这意味着口径定义必须能够被机器解析和执行,而非依赖人工阅读文档后手动操作。

阶段 自动化要求 IaC 实现方式
采集 自动从数据源拉取,无需手动导出 Prometheus Operator ServiceMonitor 自动发现目标
计算 口径逻辑由代码定义,定时执行 PromQL / LogQL 查询嵌入 Terraform 模板
存储 结果写入时序数据库,自动保留策略 InfluxDB / VictoriaMetrics 通过 IaC 配置 retention
告警 SLI 阈值触发自动告警,无需人工配置 Alertmanager 规则由 Terraform 管理
SLI 口径自动化流水线 数据源采集 口径计算引擎 时序存储 告警触发 IaC 编排层(Terraform / Pulumi / Crossplane) 自动化关键约束: • 口径定义必须为机器可解析的结构化格式(YAML / HCL / JSON) • 全链路无人工干预,从采集到告警由 CI/CD 流水线驱动

3.4 面向用户:从用户体验反向定义指标

面向用户原则要求 SLI 口径直接反映最终用户或下游服务所感知的服务质量,而非内部基础设施的健康状态。一个常见的反例是:用 CPU 使用率作为 API 服务的 SLI,但用户只关心请求是否成功返回。

常见误区: 将基础设施指标(CPU、内存、磁盘)直接作为 SLI。这些指标应作为“资源饱和度信号”用于容量规划,而非用户感知的服务等级指标。

面向用户的 SLI 口径设计应遵循以下优先级:

  1. 用户请求成功率: 从客户端或网关层采集,而非服务端内部日志。
  2. 端到端延迟: 测量从用户发起请求到收到完整响应的时间,排除服务端内部处理时间。
  3. 可用性: 用户视角下服务是否可访问,而非服务进程是否存活。
  4. 吞吐量: 用户实际完成的请求数,而非服务端处理的请求数(排除重试、爬虫等非用户流量)。
面向用户的 SLI 口径设计层次 最终用户 API 网关 / 负载均衡 后端服务 SLI 采集位置优先级 1. 用户端真实测量(RUM) 2. 网关层代理测量 3. 服务端内部测量 原则: 越靠近用户,SLI 越真实 越靠近服务,SLI 越易采集

3.5 四项原则的冲突与权衡

在实际 IaC 项目中,四项原则之间可能存在冲突。例如,面向用户要求从客户端采集数据(更真实),但可自动化要求数据源必须稳定可编程(客户端采集往往受限于网络环境和用户设备)。下表总结了常见冲突场景及推荐权衡策略:

冲突对 典型场景 推荐权衡
面向用户 vs 可自动化 客户端 RUM 数据不稳定,难以自动化采集 以网关层数据为主 SLI,客户端数据作为辅助验证
明确性 vs 可重复性 精确到毫秒的延迟定义,但不同采集工具精度不同 统一采集工具版本,并在口径定义中声明精度误差范围
可自动化 vs 明确性 自动化要求简单规则,但业务场景需要复杂判定 将复杂判定拆分为多个原子 SLI,由编排层组合计算
IaC 最佳实践: 在 Terraform 模块中为每个 SLI 定义 sli_priority 标签(user-facing / automated / precise / repeatable),当冲突发生时,根据标签优先级自动选择口径实现方案。例如,user-facing: true 的 SLI 优先使用网关层数据源,即使自动化成本更高。