proxy_read_timeout 触发于Nginx收到响应头后等待响应体数据的空闲超时,非整请求耗时;长轮询下需设为略大于后端最大等待时间,并关闭缓冲、调高相关超时及使用HTTP/1.1。

排查 proxy_read_timeout 与后端长轮询(Long Polling)接口的冲突,核心在于理解该指令的实际作用时机,并确保它不早于后端响应时间被触发中断连接。
明确 proxy_read_timeout 的触发条件
该参数控制的是 Nginx 从后端服务器读取响应体时的超时时间,不是整个请求生命周期的总耗时限制。它从 Nginx 收到后端返回的响应头之后开始计时,等待响应体数据到达的空闲时间上限。若后端采用长轮询(如挂起连接、延迟返回完整响应体),而响应体迟迟未发,Nginx 就会在此时限后主动关闭连接,导致客户端收到 504 Gateway Timeout。
- 即使后端已返回状态行和响应头(如
HTTP/1.1 200 OK),只要后续响应体没发完或没发,proxy_read_timeout就持续计时 - 它不关心后端是否还在处理逻辑,只看“有没有新数据可读”
- 默认值通常为 60 秒,对长轮询极易触发中断
检查长轮询接口的真实行为
确认后端是否真正在用长轮询模式,而非误判为“慢接口”。可通过以下方式验证:
- 用
curl -v直连后端,观察响应头中是否有Transfer-Encoding: chunked或明确的Content-Length,再看响应体是否延迟出现 - 查看后端日志:请求进入后是否立即写响应头但延迟写响应体?有无类似 “waiting for event”、“holding connection” 的记录?
- 用
tcpdump或 Wireshark 抓包,确认 TCP 连接在返回响应头后长期空闲,直到事件发生才推送数据
调整 Nginx 配置以适配长轮询
关键不是盲目调大 proxy_read_timeout,而是结合业务最大等待时长合理设置,并辅以其他配套配置:
- 将
proxy_read_timeout设为略大于后端最长可能等待时间(例如后端最多等 30 秒,则设为35s) - 同步调整
proxy_send_timeout(Nginx 向后端发请求体的超时)和proxy_connect_timeout(建连超时),避免其他环节先中断 - 禁用缓冲:
proxy_buffering off;,防止 Nginx 缓存响应体并提前结束读取判断 - 确保
proxy_http_version 1.1;,避免 HTTP/1.0 下连接复用问题干扰长轮询
验证与观测手段
改完配置后需实测+日志交叉验证:
- 开启 Nginx error log 的
info级别,关注是否仍有upstream timed out (110: Connection timed out)记录 - 在 access log 中加入
$upstream_response_time和$status,筛选出 504 请求,对比其 upstream 耗时是否接近proxy_read_timeout值 - 用浏览器 DevTools 或 Postman 观察请求是否稳定在预期时长完成,不再被 Nginx 截断


















