为了压 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 秒以内,长回答全部以完整段落结束。
提醒一点。超时值该跟着输出长度的分布走,拍一个固定秒数总会牺牲一头,分段超时更接近真实链路。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
