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

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

平均 80ms,查询界面却一卡就是 3 秒

在 TT Lab 中继续学习

目标

把含糊的客户话语转写成可测量的标准表,并制作一个验收测试运行器:读取标准表、发送请求,并留下证据和判定。只有正常构建才能通过验收,有缺陷的构建必须在对应的标准上被判为不合格。

为什么重要

“要快”既可以用平均值来测,也可以用 p95 来测,而 p95 的值还会因计算方法不同而变化。如果不连“测什么、怎么测”也达成一致,交付之后就会对着同一个数字说不同的话。 把基准值写进代码,标准变化的那天运行器就会悄悄出错。只有判定而没有证据的报告,客户无法验证。 评分器会在自己的端口上启动模拟报价服务器,构建出长尾很慢的、偶尔卡住或返回 500 的、金额差 1 韩元的、重新查询结果不稳定的构建,每次都更换基准值、用例表和会变化的字段名来运行你的运行器,然后用证据重新计算指标,并与报告核对。

预计 60 分钟。请在默认会话结束前用“+时间”延长(最长 180 分钟)。会话结束后 /root 中的文件会消失,所以代码要另外保存。

步骤

  1. 阅读客户邮件和会议纪要,把达成一致的标准写入 /root/accept/criteria.json。写的是会议上达成一致的数字和测量条件,而不是采购团队负责人最初希望的数字。
  2. 让 /root/accept/accept.py 按标准表中的 passes 次数查询用例表并留下 samples.jsonl,判定 p95_ms(nearest-rank)标准,给出 report.json 和退出码 0、1。
  3. 在 accept.py 中加入 error_rate。把非 200 的响应和 timeout_ms 内没有到达的响应算作错误,并在证据的 status 中留下“timeout”。
  4. 在 accept.py 中加入 mismatches。只把第 1 轮收到 200 的用例与 expected_total 比较,并把出错的用例 id 留在 mismatched_cases 中。
  5. 在 accept.py 中加入 rerun_diffs。对第 1、2 轮都是 200 的用例,用去掉标准表中 ignore_fields 的正文进行比较,并留下 rerun_diff_cases。
  6. 在同时使用四项标准的标准表中,原样遵循 op(<、<=、==),并让报告中的 observed、pass、metrics 与用证据重新计算的值相同。
  7. 用新改动的标准表运行五个候选(正常、长尾很慢、偶尔 500、金额错误、重新查询不稳定),确认只有正常的才通过验收。
  8. 用 python3 /opt/lab/p1a-criteria/quote_server.py --port 8095 --build rc2 启动客户候选 rc2,用 criteria.json 和提供的用例表运行,并在 /root/accept/rc2/ 中留下 report.json 和 samples.jsonl。

参考

把四个形容词变成四个数字

为每一句客户话语确定 metric、op、threshold、source,并连同 timeout_ms、passes、ignore_fields 一起写入 /root/accept/criteria.json。

会议纪要里混有最初提出的期望数字和最终达成的一致意见。百分比写成比例(小数),时间写成以 ms 为单位的整数。source 写明该标准出自哪句客户原话。

用 p95 而不是平均值抓住慢的长尾

让 /root/accept/accept.py 把用例表查询 passes 次,留下 samples.jsonl,并判定 p95_ms 标准。

为每个请求留下用 time.perf_counter 测得的 ms,把所有请求的 ms 排序后选出第 ceil(0.95 × n) 个值。statistics.quantiles 的默认值是插值,会得出不同的值。请求数正好是 passes × 用例数。

没有到达的响应也算作错误

在 /root/accept/accept.py 中加入 error_rate,把非 200 的响应和超过 timeout_ms 的情况算作错误。

把标准表中的 timeout_ms 换算成秒,传给 urlopen 的 timeout 参数。HTTPError 是带有状态码的响应,超时则以 TimeoutError、URLError 的形式出现。证据的 status 中要把 timeout 作为字符串留下。

找出差 1 韩元的金额

在 /root/accept/accept.py 中加入 mismatches,把第 1 轮 200 响应的 total 与 expected_total 比较,并留下 mismatched_cases。

CSV 中的 expected_total 是字符串,要转成整数再比较。错误响应已经在错误率中计算过,所以金额比较时要排除。同一个问题在两项标准中被重复计算,就分不清是哪项标准造成的了。

查询两次,找出不稳定的用例

在 /root/accept/accept.py 中加入 rerun_diffs,比较去掉标准表 ignore_fields 之后的第 1、2 轮正文,并留下 rerun_diff_cases。

如果把 request_id 这样的字段名写进代码,评分器一改字段名,正常构建就会被判为不合格。请只从字典中去掉标准表里的字段再比较。

自己核对报告是否与证据一致

让 /root/accept/accept.py 按标准表的 op 原样判定四项标准,并让 report.json 中的 observed、pass、metrics 与用 samples.jsonl 重新计算的值相同。

op 用把字符串映射为运算的表来处理。错误率与基准值恰好相等时,< 为失败,<= 为通过。threshold 原样搬运标准表的值,证据在请求之后逐行写入。

用改动后的标准表区分五个候选

确认 /root/accept/accept.py 在新基准值、新用例表、新的变化字段名下,也只让正常候选通过验收,而有缺陷的候选只在对应的一项标准上不合格。

如果一个缺陷同时让多项标准不合格,就无法区分原因。请查找是否还有把基准值、字段名、用例写进代码的地方。

判定客户候选 rc2 是否通过验收

在端口 8095 上启动 rc2 服务器,用 criteria.json 和提供的用例表运行,并留下 /root/accept/rc2/report.json 和 /root/accept/rc2/samples.jsonl。

不要为了迎合结果去修改标准表。评分器会检查 criteria.json 是否与第 1 步达成的一致相同、报告是否与证据一致、证据是否真的是 rc2 的响应。服务器用完之后,只挑出该 PID 来终止。