2. SLI 口径设计原则:如何定义有效的 SLI 口径,关键指标(成功率、延迟、吞吐量)的选择
SLI(Service Level Indicator,服务等级指标)是 SRE 实践的基石。在 GitLab CI 流水线场景中,SLI 口径定义的质量直接决定了故障排查的效率和告警降噪的效果。一个错误的 SLI 口径可能掩盖真实故障,或产生大量无意义的告警。
2.1 有效 SLI 口径的三大设计原则
定义 SLI 时,必须遵循以下原则,确保指标能够真实反映用户体验和系统健康度:
| 原则 | 说明 | 反例 |
|---|---|---|
| 贴近用户 | SLI 应度量用户(开发者、QA、运维)实际感知的行为,而非内部组件状态。 | 用“Runner CPU 使用率”代替“Job 排队时间”。 |
| 可测量 | 口径必须能从现有日志、指标、追踪数据中精确提取,避免模糊定义。 | “流水线运行流畅度”这种无法量化的描述。 |
| 可区分 | 不同故障模式应映射到不同的 SLI 降级,避免一个指标覆盖所有异常。 | 将“构建失败”和“部署超时”合并为一个“流水线异常”指标。 |
实践要点: 在 GitLab CI 中,最贴近用户的 SLI 是 Job 状态(成功/失败)和 Job 持续时间。避免使用 Runner 心跳或容器资源利用率作为流水线 SLI。
2.2 三大关键指标的选择与口径定义
在 GitLab CI 流水线场景中,我们聚焦于三个核心 SLI:成功率、延迟、吞吐量。每个指标都需要精确的口径定义。
2.2.1 成功率(Success Rate)
成功率是最直观的 SLI,但口径定义需要细化:
- 口径定义: 在统计窗口内(如 5 分钟),
status = 'success'的 Job 数 / 总完成 Job 数。 - 排除项: 手动取消的 Job(
canceled)不应计入分母,因为这是人为操作而非系统故障。 - 失败分类: 需要区分
failed(脚本错误)和skipped(条件跳过),前者是 SLI 降级,后者不是。
# PromQL 示例:计算 GitLab CI Job 成功率(排除手动取消)
sum(rate(gitlab_ci_job_duration_seconds_count{status="success"}[5m]))
/
sum(rate(gitlab_ci_job_duration_seconds_count{status=~"success|failed"}[5m]))
2.2.2 延迟(Latency)
延迟 SLI 关注流水线或 Job 的响应速度,口径定义需明确“从何时到何时”:
- 口径定义: Job 从
created状态变为running状态的等待时间(Queueing Latency),以及从running到success/failed的执行时间(Execution Latency)。 - 分位数选择: 推荐使用 p99(极端延迟)和 p50(典型延迟),避免使用平均值(易被极端值掩盖)。
- 阈值设定: 例如,p99 排队时间 > 60 秒 视为 SLI 降级。
关键区分: 排队延迟高通常意味着 Runner 资源不足或调度器瓶颈;执行延迟高则可能是构建脚本、依赖下载或测试环境问题。两者需要分开度量。
2.2.3 吞吐量(Throughput)
吞吐量 SLI 反映系统处理能力,口径定义需关注“完成量”:
- 口径定义: 单位时间内成功完成的 Job 数(或流水线数)。
- 与成功率的关系: 吞吐量下降可能是成功率降低的后果,也可能是系统容量不足的独立信号。
- 场景示例: 当 Runner 集群发生故障时,吞吐量会骤降,即使剩余 Job 的成功率仍为 100%。
2.3 SLI 口径设计流程:从原始数据到有效指标
以下 SVG 展示了从 GitLab 原始事件到最终 SLI 口径的转换流程:
2.4 口径定义中的常见陷阱与避坑指南
| 陷阱 | 错误口径 | 正确做法 |
|---|---|---|
| 包含手动操作 | 将手动触发的流水线纳入 SLI 统计 | 仅统计 CI/CD 自动触发的流水线(如 merge request、push) |
| 忽略重试 | 将重试成功的 Job 计为失败 | 以最终状态为准,重试成功视为成功;但需单独追踪重试率 |
| 窗口过小 | 使用 1 分钟窗口计算成功率 | 使用 5-15 分钟窗口,避免因单次失败导致告警抖动 |
| 未区分阶段 | 将 build、test、deploy 阶段的延迟混在一起 | 按阶段拆分 SLI,每个阶段独立设置阈值 |
重要警告: 不要试图用一个“综合健康度”指标覆盖所有场景。在 GitLab CI 中,成功率、延迟、吞吐量 三个 SLI 必须独立定义、独立采集、独立告警。混合指标会导致故障定位时无法快速确定根因。
2.5 小结:SLI 口径定义检查清单
在定义每个 SLI 口径时,请对照以下清单进行验证:
- 是否可测量? 该指标能否从 GitLab 暴露的 Prometheus metrics 或 API 日志中直接获取?
- 是否可区分? 该指标降级时,能否唯一对应一种故障模式(如资源不足、脚本错误、网络延迟)?
- 是否排除噪音? 手动取消、条件跳过、重试等非故障事件是否已从分母中排除?
- 是否设置合理窗口? 统计窗口是否足够大以过滤瞬时抖动,又足够小以快速发现持续故障?
- 是否分阶段? 对于延迟指标,是否区分了排队延迟和执行延迟?
遵循以上原则和流程,你定义的 SLI 口径将具备高信噪比,为后续的告警规则和故障排查打下坚实基础。