内网网关到推理服务是 nginx 1.24 反代,长回答平均 38 秒。proxy_read_timeout 查出来还是默认的 60 秒,可客户端每次都在 30 秒收到 504,错误日志里写着 upstream timed out while reading response header。改客户端超时没有任何效果,换 curl 也一样。

一开始怀疑是「send_timeout 和 read_timeout 混在一起改,方向错了」,查了一圈,方向不对。

原因不止一个,得分开看。上一跳负载均衡的空闲超时是 30 秒,比 nginx 更早断。另一种情况是推理服务边算边发但没有心跳,连接被判成空闲。

还有一种情况,客户端 SDK 自带 30 秒默认值,把真实现象盖住了。

上来先逐层确认超时配置的实际取值

nginx -T 2>/dev/null | grep -E 'proxy_read_timeout|proxy_send_timeout'

随后用带计时的 curl 看究竟断在第几秒

curl -N -w 'time_total=%{time_total}\n' http://gw.local/v1/chat -d @body.json

再往下让上游边算边发并补上 SSE 心跳

curl -N http://127.0.0.1:8000/v1/chat -d @body.json | head -n 5

剩下的就是按链路最长耗时统一各层超时并留两成余量

python -c "print(int(45*1.2))"

别只看报错消失,验证要多做一步。同样的长请求能完整返回,curl 记录的 time_total 超过 45 秒仍为 200,网关错误日志里不再出现 upstream timed out。

超时要按整条链路最短的那一层算,客户端、负载均衡、nginx、应用四处默认值经常各不相同,只改一处不够。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189