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 管理 |
3.4 面向用户:从用户体验反向定义指标
面向用户原则要求 SLI 口径直接反映最终用户或下游服务所感知的服务质量,而非内部基础设施的健康状态。一个常见的反例是:用 CPU 使用率作为 API 服务的 SLI,但用户只关心请求是否成功返回。
常见误区: 将基础设施指标(CPU、内存、磁盘)直接作为 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 优先使用网关层数据源,即使自动化成本更高。