TT Lab
开始
学习 学习路径 课程

FDE综合实战:仓库收到了三次相同订单

客户只写了“要快”

在 TT Lab 中继续学习

一句话总结

验收标准是把客户的形容词转换成指标、计算方法、基准值、测量条件这四块;验收测试运行器则在代码之外读取这张标准表、发送请求,并同时留下证据和判定。

为什么需要它

采购团队的邮件里只有一行:“报价查询必须很快。”开发团队说平均 80ms,所以很快;运维团队说昨天下午查询页面每次都卡住 3 秒。两边说的都是事实。每二十次就卡一次的服务,按平均值来看是很快的。如果验收会议上没有把这种差异摆出来,交付之后,“你们说过很快的呀”和“明明不快啊”就会撞在一起。

对 FDE 来说,验收标准不是文书工作,而是协商的成果。要把客户想要的体验换算成数字,而且必须连这个数字测的是什么、怎么测的也一并达成一致,以后才不会对着同一个数字说不同的话。而且,如果把谈定的数字写死在代码里,每次标准变化都得修改运行器,也分不清哪个版本的运行器依据哪个标准做出了判定。这就是要把标准表放在文件里的原因。

工作原理

Google SRE 书中的服务级别目标一章警告说,只用平均值汇总 SLI,会掩盖“大部分很快、长尾却慢得多”的情况,并建议用百分位数来观察分布的形状。同一章把 SLO 的自然形式写成“SLI ≤ 目标”。本实验标准表中的一行,正是这个形状。

{"id": "quote-latency", "metric": "p95_ms", "op": "<=", "threshold": 250,
 "source": "견적 조회가 빠르게 되어야 합니다"}

必须连计算方法也写下来。“p95”不是一个确定的值。Python 的 statistics.quantiles 默认是 exclusive 方式,在两个样本之间做线性插值,另外还有 inclusive 方式。实测中,对 40 个请求里 38 个是 5ms、2 个是 400ms 的情形比较了三种方式:nearest-rank(排序后取第 ceil(0.95×n) 个值)是 5.0,quantiles(n=100) 的第 95 个切分点,exclusive 是 380.25,inclusive 是 24.75。如果基准值是 250ms,同一份证据会因方式不同而既可能通过也可能失败。所以要在契约中明确写出 nearest-rank,并让任何人都能用证据重新计算。

测量条件也是标准。延迟是从发出请求到收完响应正文为止,用 time.perf_counter 来测。文档把这个时钟说明为测量短时间间隔的最精确的时钟,并写明它没有规定基准点,只有两次调用之差才有意义。在 CPython 中,它和不会倒退的 monotonic 时钟是同一个时钟。相反,同一份文档写明,如果两次调用之间系统时钟被向后调整,time.time() 可能返回更小的值,所以不用它来测量时间间隔。错误率首先要看“把什么算作错误”。和这位客户约定,非 200 的响应和 1000ms 内没有到达的响应都要计入。urllib.request 文档把 urlopen 的 timeout 说明为对连接尝试这类每一个阻塞操作的限制。这意味着它不是整个请求的截止时间,所以对一点一点慢慢发送的服务器,耗时可能比基准更长。运行器把测得的时间原样留在证据中,以便暴露这种情况。

正确性和可重现性要分开测。正确性与客户提供的用例表中的期望值比较,可重现性则是把同一张用例表查询两次,让结果互相比较。在第二种比较中,要去掉 request_id 或生成时间这类每次变化才正常的字段,而去掉哪些字段,也写在标准表里。如果写在代码里,服务器一改字段名,正常构建就会被判为不合格。

客户的话 指标 标准 测量条件
要快 p95_ms (nearest-rank) 250 以下 整个请求,直到收完正文
不能出错 error_rate 0.01 以下 非 200 + 超过 1000ms
金额要对 mismatches 0 第 1 轮,与用例表的期望值比较
重跑也要一样 rerun_diffs 0 比较第 1、2 轮,排除变化的字段

在现场相遇的样子

最常见的失败是只有判定的报告。只收到一句“验收测试通过”的客户运维团队,没有办法验证这句话,两个月后出了故障,就得从头追问测试测的到底是什么。如果有逐个请求记录了延迟、状态和响应的证据,客户就能用自己的方式重新计算。证据中重新算出的值与报告中的值不同,就不能相信这份报告。本实验评分器做的,正是这件事。

第二个是事后修改标准。候选构建在金额标准上不合格,于是有人说“差 1 韩元是四舍五入,允许吧”,就改了标准表再跑一遍。也许确实需要容差。但那是要与客户重新协商的事,而不是运行了运行器的人看完结果再决定的事。把基准值原样抄进判定报告,原因也在这里。

实际工作中真正重要的事

下一项实验要做什么

把客户邮件和会议纪要转写成标准表,然后依次把延迟、错误率、正确性、可重现性放进运行器。评分器会用模拟报价服务器启动长尾很慢的构建、偶尔卡住或返回 500 的构建、部分金额差 1 韩元的构建、重新查询结果不稳定的构建,并且每次都更换基准值和用例表来运行你的运行器。最后,亲自启动客户的候选 rc2,判定是否验收。