LabHub
学习 学习路径 课程

CNPE — 云原生平台工程师

100%成功率背后的错误分母

在 LabHub 中继续学习

一句话总结

SLI 的第一个问题不是公式,而是什么算一次、遗漏了哪些失败。即使精确计算错误插桩的数据,也得不到正确的用户体验指标。

概念图: 什么算一次、遗漏了哪些失败 · 真实执行的层与人为设定的原因

为什么需要它

假设自助数据库发放 API 成功返回 201,依赖故障返回 503,但计数器只在成功 handler 末尾增加。发送两个成功和两个失败,指标只留下 success=2、total=2,面板显示 100%,实际响应成功率却是 50%。把阈值从 99.9% 提到 99.99% 也发现不了问题。

后续练习会在 Pod 中运行真实 Python HTTP server,实际接收 201、503、504,而不是伪造图片。故障由练习专用 X-Lab-Scenario header 选择,不会真的关闭外部数据库。必须说明真实执行的层与人为设定的原因,才能界定证据范围。

工作原理

先决定一次的单位

Google SRE SLO 实现指南建议从用户重视的行为设计可测指标和目标。这里以发放 API 的一次 HTTP 尝试为单位。失败尝试 a 后的成功重试 b 是两次;若因最终成功而合并为一次,就混淆了尝试级与用户任务级指标。两者回答不同问题,并非总有一个正确。

练习 scope.json 把 /provision 的 2xx、5xx 视为 eligible,排除 4xx 和健康检查路径。这是虚拟契约,不能直接复制到生产。例如因服务容量不足产生 429 时,不能简单归为用户错误并排除。需约定请求有效性与服务责任,并观测排除比例,防止为了让指标好看而改变范围。

区分可用性和速度

eligible 是分母中的尝试,available 是其中 2xx,fast 是成功且服务端耗时不超过 1000ms。1000ms 包含,1000.1ms 排除;快速 503 不算 fast,慢 201 算 available 但不算 fast。两个 SLI 使用同一分母,分子不同。

事件 eligible available fast
正常 201,10ms
慢 201,1100ms
失败 503,10ms
输入错误 400

还要说明测量位置。服务端处理时间不完全包含客户端网络往返和连接等待,不能把本练习的服务端时间扩大为完整用户延迟证明;若目标是浏览器可见延迟,还需在该位置观测。

主动发送失败并核对两份记录

Prometheus 插桩原则可用于设计 counter、failure、label。练习 server 不把 user ID 或 request ID 放进指标,只暴露 observed、eligible、available、fast 四种有限序列。唯一请求 ID 用于日志追踪,避免用户增长导致无限时序。

HTTP 重放要把七个响应与 observed=7 对上,再核对分母 4、available 2、fast 1。/metrics 抓取本身不能再次计入业务请求。不能只看“指标为 100%”,而要连接“确实发送失败”和“失败确实进入分母”。系统会用当前代码重新执行,旧的正常结果文件不足以证明正确。

现场表现

若采集器把同一日志发送两次,attempt_id 和内容相同则是采集重复,只分类一次并另记重复数。同一 ID 状态码不同则无法判断,应抛出 ValueError 暴露冲突,不能任意选最后一个,以免失败被成功覆盖。不同 ID 的重试是不同尝试,应全部计数。

这只是小型练习 JSON 事件的规则。生产中多个服务发放 ID 时,还要设计冲突域与保留期;本任务不声称实现分布式 exactly-once 或永久去重。

下一步

接下来学习在分母可信时允许多少失败,以及数据为空时哪些结论无法得出。后续练习会连接分类函数、真实 HTTP、去重、错误预算和自行设计的反例。