为了压 P99 把网关超时从 30 秒改成 8 秒,接口 P99 从 12 秒降到 7.4 秒,同时 5% 的长回答被中断,用户投诉回答不完整。

一开始怀疑是「高峰期排队时间波动,固定超时误杀了正常请求」,查了一圈,方向不对。

原因不止一个,得分开看。长回答的生成时间与服务端排队时间都算在同一个超时里。另一种情况是超时按整条请求算,而不是首 token 时间。

少数情况下是被中断的请求仍然照常计费。

第一件事是把超时拆成连接与读取两段

python -c "import httpx;print(httpx.Timeout(connect=3,read=20,write=5,pool=5))"

随后统计被中断请求的占比

python -c "print(round(0.05*100,1))"

长回答改走异步任务轮询

python -c "print({'mode':'async','poll':'/v1/tasks/{id}'})"

压测复现延迟分布看 P99

python -c "import numpy as np;print(round(float(np.percentile(np.random.normal(4,3,1000),99)),2))"

别只看报错消失,验证要多做一步。超时中断率降到 0.5% 以下,P99 仍在 8 秒以内,长回答全部以完整段落结束。

提醒一点。超时值该跟着输出长度的分布走,拍一个固定秒数总会牺牲一头,分段超时更接近真实链路。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189