先把当时的情况摆出来。pytest 跑 1200 条评测用例,每条用例里都 OpenAI() 新建客户端,全套跑完 41 分钟,抓包看 TLS 握手占了 30 分钟。
这类报错背后常见的原因有几处,逐个排除就行。每个用例新建 client,连接和 TLS 全部重来。还有一种是fixture 的 scope 写成了 function。
少数情况下是没有并行执行,1200 条串行。不容易想到的是,每条用例还重新读了配置文件。
上来先统计单条用例的连接耗时
python -c "import time,openai;t=time.time();openai.OpenAI();print(round(time.time()-t,3))"
随后把 fixture 改成 session 级复用
python -c "import pytest;print(pytest.__version__)"
然后用 xdist 按 4 进程并行
pytest -n 4 --dist loadfile -q
剩下的就是对比改造前后的总耗时
pytest --durations=10 -q
隔了一天再看,现象没变,说明不是偶发。
那几天正好在做别的变更,先把时间线对齐才敢动手。
排查用的命令都是临时敲的,没有写成脚本,事后才整理。
恢复的判定其实很直接。全套耗时从 41 分钟降到 7 分钟,TLS 握手次数从 1200 次降到 4 次,用例通过数不变。
这里还有个坑。评测脚本的耗时经常花在建连上而不是推理上,client 的生命周期要和 fixture 的 scope 对齐。这类问题最好一次改到位,反复小改反而容易把原因搅混。
