proxy_read_timeout与upstream keepalive必须协同调优:前者按后端P99耗时×1.2–1.5设定并小于后端read timeout,后者需配合proxy_http_version 1.1和proxy_set_header Connection ''才能生效。
调优
proxy_read_timeout
和
upstream keepalive
是解决耗时业务(如报表导出、AI 推理、批量同步)频繁 504 的关键组合,但二者必须协同生效——单改一个,效果几乎为零。
proxy_read_timeout 要匹配真实业务耗时,不是堆数字
它只管 Nginx 等待后端响应体第一个字节的空闲时间,不是整个请求生命周期。设得太小,后端还在跑就被断;设太大,worker 进程被长期占用,拖垮并发能力。
先查后端接口真实 P95/P99 耗时(比如 /api/export 的平均是 210 秒,P99 是 340 秒)
取 P99 × 1.2~1.5,得到合理值(如 340 × 1.3 ≈ 440 秒 → 设为
480
)
必须比后端自身超时长 3–5 秒(如 Tomcat 的
,Nginx 就不能设 ≤40 秒)
避免全局统一设高值,用
块对导出路径单独配置,不影响其他 API
keepalive 不是配了就自动复用,得满足三个前提
只写
没用。连接要真正复用,必须同时满足:
:确保发 HTTP/1.1 请求
:清空 Connection 头,避免被后端误判为 close
后端支持 Keep-Alive 且不主动断连(Spring Boot 需确认
不为 -1)
keepalive 数值建议从 32 起步,高并发场景可按每 worker 并发量 × 0.8 估算,不建议超过 100
二者不配合会引发“假超时”和连接池雪崩
常见错误场景:
proxy_read_timeout 设为 600,但 keepalive 未启用 → 每次请求都重建连接,握手+TLS 耗掉 3–5 秒,实际留给业务的时间只剩 595 秒,波动大时仍易超时
keepalive 开了,但 proxy_read_timeout 还是默认 60 → 后端第 61 秒才返回首字节,Nginx 直接断连,复用毫无意义
后端响应慢,而系统级
设为 600(10 分钟),早于 proxy_read_timeout,内核先发 FIN,Nginx 收到 RST 后报
,日志里却显示 “timeout”
配套必须检查的三件事
光调这两个参数还不够,漏掉任一环都会让优化失效:
proxy_send_timeout
必须 ≥ proxy_read_timeout:防止请求体还没发完就被切断
send_timeout
也需同步放大:尤其客户端网络差、下载大文件慢时,否则 Nginx 会提前关 client 连接
开启 upstream 日志字段
:
和
,定位到底是卡在建连、发请求,还是真正在等响应
connectionTimeout=40000locationkeepalive 32proxy_http_version 1.1proxy_set_header Connection ''server.connection-timeoutnet.ipv4.tcp_keepalive_timeupstream timed out (110)$upstream_response_time$upstream_connect_time