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 口径的转换流程:

SLI 口径设计流程 SLI 口径设计流程:从原始事件到有效指标 原始事件 Job created/running/done 数据采集 Prometheus / 日志 口径定义 排除/聚合/分位数 SLI 输出 成功率/延迟/吞吐量 成功率 成功 Job / 总完成 Job 排除 canceled 延迟 排队延迟 + 执行延迟 p99 / p50 分位数 吞吐量 成功 Job 数 / 时间 单位:Job/min 核心原则:每个 SLI 必须对应一个明确的故障模式,避免“万能指标” 成功率降级 → 脚本/环境故障;延迟降级 → 资源/网络瓶颈;吞吐量降级 → 容量/调度问题

2.4 口径定义中的常见陷阱与避坑指南

陷阱 错误口径 正确做法
包含手动操作 将手动触发的流水线纳入 SLI 统计 仅统计 CI/CD 自动触发的流水线(如 merge request、push)
忽略重试 将重试成功的 Job 计为失败 以最终状态为准,重试成功视为成功;但需单独追踪重试率
窗口过小 使用 1 分钟窗口计算成功率 使用 5-15 分钟窗口,避免因单次失败导致告警抖动
未区分阶段 将 build、test、deploy 阶段的延迟混在一起 按阶段拆分 SLI,每个阶段独立设置阈值
重要警告: 不要试图用一个“综合健康度”指标覆盖所有场景。在 GitLab CI 中,成功率、延迟、吞吐量 三个 SLI 必须独立定义、独立采集、独立告警。混合指标会导致故障定位时无法快速确定根因。

2.5 小结:SLI 口径定义检查清单

在定义每个 SLI 口径时,请对照以下清单进行验证:

  1. 是否可测量? 该指标能否从 GitLab 暴露的 Prometheus metrics 或 API 日志中直接获取?
  2. 是否可区分? 该指标降级时,能否唯一对应一种故障模式(如资源不足、脚本错误、网络延迟)?
  3. 是否排除噪音? 手动取消、条件跳过、重试等非故障事件是否已从分母中排除?
  4. 是否设置合理窗口? 统计窗口是否足够大以过滤瞬时抖动,又足够小以快速发现持续故障?
  5. 是否分阶段? 对于延迟指标,是否区分了排队延迟和执行延迟?

遵循以上原则和流程,你定义的 SLI 口径将具备高信噪比,为后续的告警规则和故障排查打下坚实基础。