网关到模型服务的读超时设 10 秒,而推理在长上下文下要 45 秒才出首包,客户端断开后上游继续算,重试三次把 GPU 队列直接打满。
一开始怀疑是「重试没有区分连接超时与读超时」,查了一圈,方向不对。
这类报错背后常见的原因有几处,逐个排除就行。读超时短于正常推理时长,所有长请求都被判失败。也可能是客户端断开没有取消上游计算,算力被白烧。
不容易想到的是,入口没有排队上限,失败请求反复涌回。
量一次首包时间与总耗时
curl -o /dev/null -s -w '%{time_starttransfer} %{time_total}\n' https://api.example.com/v1/chat/completions -d @req.json
随后把读超时按 P99 首包时间放大两倍
python -c "print({'connect_timeout':3,'read_timeout':90})"
再往下改用流式,首包到了就重置超时计时
curl -N https://api.example.com/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"gpt-4o-mini","stream":true,"messages":[{"role":"user","content":"写一段摘要"}]}'
断开时主动取消上游请求并限制并发
python -c "print({'cancel_on_disconnect':True,'max_inflight':24})"
恢复的判定其实很直接。长上下文请求的失败率从 8% 降到 0.5%,GPU 上不再出现大量无效任务,重试次数也回落到正常水平。
补一句。超时值要按真实耗时分布来定,服务端断开不等于上游停止,取消传播和并发上限比调大超时更能保护后端。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
