nginx对502/504的自动重试需三步验证:一确认proxy_next_upstream显式包含http_502 http_504且配全tries/timeout及健康检查;二通过停服务或注入延迟触发故障;三通过access_log中不同upstream_addr与status组合及error.log重试痕迹证实请求真实重试并成功。

验证生产环境中 Nginx 对 502/504 的自动重试是否生效,不能只看配置写了没,关键要确认“请求真被重试了、且成功落到其他节点”,同时避免误触发或副作用。核心是三步:确认重试机制已启用、构造可控故障触发重试、观察日志与链路证据。
检查 proxy_next_upstream 配置是否完整启用
仅写 proxy_next_upstream error timeout 是不够的——默认不包含 502 和 504。必须显式加入:
-
proxy_next_upstream error timeout http_502 http_504;(推荐加http_503) -
proxy_next_upstream_tries 3;(最多尝试 3 次,含首次) -
proxy_next_upstream_timeout 6s;(从第一次发起到超时的总窗口,不是单次) - upstream 中每个 server 后需带健康检查参数,例如:
max_fails=3 fail_timeout=30s
配置后 reload Nginx,并用 nginx -t 确保语法正确。注意:这些参数必须放在 location 或 server 块中,且作用域需覆盖目标 upstream。
用可控方式触发 502/504 并验证重试行为
别等线上崩了再试。可在测试环境或灰度节点上模拟故障:
- 临时停掉某台后端服务(如
systemctl stop php-fpm),发起请求,观察是否返回 502 并快速切到其他节点 - 在某台后端上注入延迟(如用
sleep 10模拟慢响应),确保proxy_read_timeout小于该值(如设为 5s),触发 504 后看是否重试 - 对 GET 请求发起多次调用,用
curl -v观察响应头中的X-Upstream-Addr(可由后端注入)或 Nginx 的$upstream_addr变量(通过add_header X-Upstream $upstream_addr;输出)
若看到同一请求返回了不同后端 IP(如 10.0.1.10:8000, 10.0.1.11:8000),说明重试已生效。
从 Nginx error.log 和 access.log 找重试证据
真正可靠的验证依据来自日志,不是状态码本身:
- 在
error.log中搜索upstream: "http://..."+while connecting to upstream或while reading response header from upstream,出现多次且 upstream 地址不同,即为重试痕迹 - 开启详细 access log,添加
$upstream_addr $upstream_status $request_time $upstream_response_time字段。一次请求若对应多条日志(如10.0.1.10:8000 504 5.002 5.001后紧跟10.0.1.11:8000 200 0.042 0.041),就是成功重试 - 注意:
proxy_next_upstream_timeout超时后,Nginx 会统一返回 502,但日志里仍会记录所有失败尝试,这是判断是否“尽力重试”的关键
重试只对幂等请求安全,生产环境建议仅对 GET/HEAD 开启 http_502 http_504,非幂等请求禁用,避免重复提交。











