4. 流水线成功率 SLI:定义流水线成功/失败的标准,计算口径
流水线成功率(Pipeline Success Rate)是衡量 CI/CD 交付质量最核心的 SLI 之一。它直接反映代码从提交到产出制品的整体健康度,也是故障排查和告警降噪的第一道防线。如果成功率持续低于阈值,说明交付管道存在系统性缺陷,需要立即介入。
4.1 成功与失败的标准定义
在 GitLab CI 中,一条流水线的最终状态由所有 Job 的聚合结果决定。但并非所有“非成功”状态都代表故障,需要区分业务失败与系统失败。
| 流水线状态 | 是否计入“失败” | 说明 |
|---|---|---|
passed |
否 | 所有 Job 均成功完成,视为成功流水线。 |
failed |
是 | 至少一个 Job 返回非零退出码,属于业务逻辑失败。 |
canceled |
是(按需) | 手动取消。若因上游失败自动取消,应计入失败;若人为主动取消(如停止无效提交),可排除。 |
skipped |
否 | 因 rules / only / except 条件未触发,不计入总流水线数。 |
manual |
否 | 等待手动触发,未执行完成,不计入统计窗口。 |
running / pending |
否 | 进行中或排队中,不参与当前时间窗口的统计。 |
建议口径:在计算成功率 SLI 时,只将
passed 视为成功,将 failed 和因失败自动 canceled 的流水线视为失败。手动取消和 skipped 流水线应从分母中剔除,避免稀释指标。
4.2 计算口径:总流水线数 vs 成功流水线数
成功率 SLI 的标准计算公式为:
流水线成功率 (%) = (成功流水线数 / 有效总流水线数) × 100%
其中:
- 成功流水线数 = 状态为 'passed' 的流水线数量
- 有效总流水线数 = 状态为 'passed' + 'failed' + 因失败自动 'canceled' 的流水线数量
以下通过一个实际场景说明口径差异:
| 统计维度 | 口径 A(宽松) | 口径 B(严格) | 口径 C(推荐) |
|---|---|---|---|
| 总触发流水线 | 100 | 100 | 100 |
| passed | 80 | 80 | 80 |
| failed | 10 | 10 | 10 |
| canceled(自动) | 5 | 5 | 5 |
| canceled(手动) | 3 | 3 | 3 |
| skipped | 2 | 2 | 2 |
| 分母取值 | 100(全部) | 95(排除 skipped) | 95(排除 skipped + 手动取消) |
| 成功率 | 80% | 84.2% | 84.2% |
口径 A 将 skipped 和手动取消纳入分母,会低估真实交付能力;口径 B 和 C 更准确,其中口径 C 进一步排除了人为干预因素,适合作为 SLO 的基准。
4.3 流水线成功率计算流程
下图展示了从 GitLab API 采集原始数据到产出 SLI 指标的完整链路:
4.4 告警降噪:避免误报的过滤策略
直接对原始成功率设置告警会产生大量误报。以下策略可有效降噪:
- 最小样本量过滤:在 5 分钟窗口内,若总流水线数 < 3 条,不触发告警,避免小样本波动。
- 连续失败窗口:只有连续 N 条(如 3 条)流水线失败,才产生告警,容忍偶发抖动。
- 排除已知故障窗口:在基础设施变更窗口(如 K8s 集群升级)内,自动抑制成功率告警。
- 按分支分级:对
main分支使用严格阈值(如 99%),对功能分支使用宽松阈值(如 90%)。
常见陷阱:不要将
canceled 状态全部视为失败。如果 CI 配置了“上游失败自动取消下游”,这些自动取消的流水线应计入失败分母;但如果是运维人员手动取消的重复提交,则应排除。建议在 GitLab Webhook 或 API 回调中增加 pipeline.canceled_by 判断逻辑。
4.5 成功率 SLI 的典型阈值参考
| 环境 / 分支 | 目标 SLO | 告警阈值 | 说明 |
|---|---|---|---|
| 生产部署(main) | ≥ 99.5% | < 99% 持续 10 分钟 | 任何失败都应立即排查 |
| 预发布(release/*) | ≥ 98% | < 95% 持续 30 分钟 | 允许少量环境配置问题 |
| 功能开发(feature/*) | ≥ 90% | < 80% 持续 1 小时 | 容忍开发过程中的调试失败 |
| 合并请求(MR) | ≥ 95% | < 90% 持续 30 分钟 | MR 流水线失败应快速反馈 |
实践要点:成功率 SLI 必须与“失败根因分类”联动。建议在 GitLab 流水线中为每个 Job 注入
failure_reason 标签(如 test_failure、build_error、infra_timeout),以便在告警时直接定位故障类型,避免每次都需要人工查看日志。