“504 Gateway Time-out” 常见的建议是加大 proxy_read_timeout。这篇在本机起自己的 nginx 和故意很慢的上游,把超时发生在响应头阶段还是响应体阶段、超时到底是总时长还是读间隔、GET 与 POST 的重试差别,以及默认值各测了一遍。
客户端:HTTP 504,页面标题 "504 Gateway Time-out",等了 1.02 s
error.log: [error] *2 upstream timed out (60: Operation timed out) while reading response header from upstream, request: "GET /slow HTTP/1.1", upstream: "http://127.0.0.1:9791/slow", host: "127.0.0.1:9780"
access.log: 127.0.0.1 - - [29/Oct/2026:15:19:08 +0800] "GET /slow HTTP/1.1" 504 167 "-" "Python-urllib/3.14"nginx 等上游的响应头超过 proxy_read_timeout;error.log 写明阶段。
trickle(总共约 4 s,每次间隔 0.5 s):HTTP 200,收到 8 字节,总耗时 4.03 s
stall(发了 4 字节后停住):HTTP None,收到的内容 'IncompleteRead: IncompleteRead(0 bytes read, 100 more expect',耗时 1.00 s
error.log: [error] *4 upstream timed out (60: Operation timed out) while reading upstream, request: "GET /stall HTTP/1.1", upstream: "http://127.0.0.1:9793/stall", host: "127.0.0.1:9780"是两次读之间的间隔,不是整个响应的总时长。
(上面第 1 步是前者;stall 的情形是后者,见上面 error.log)
响应头已发给客户端,之后超时只会让连接被切断,不是 504。
GET:HTTP 200 "second upstream",耗时 1.01 s
error.log: [error] *2 upstream timed out (60: Operation timed out) while reading response header from upstream, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:9794/", host: "127.0.0.1:9780"
接着连发 4 次 POST(轮询,max_fails=0 所以慢的那台不会被摘掉,每隔一次落在它上面):[(200, 0.0), (504, 1.0), (200, 0.0), (504, 1.0)]多台上游时 GET 超时会换下一台重试,POST 默认不重试。
不写 proxy_read_timeout(上游 70 s):HTTP 504,耗时 60.0 s
error.log: [error] *2 upstream timed out (60: Operation timed out) while reading response header from upstream, request: "GET /default HTTP/1.1", upstream: "http://127.0.0.1:9796/default", host: "127.0.0.1:9780"
proxy_read_timeout 5s(上游 3 s):HTTP 200 "slow ok",耗时 3.01 s默认 60 s;对慢接口单独调大,而不是全局。