Nginx的proxy_pass不自动重试,需显式配置proxy_next_upstream及相关参数;仅在proxy_pass阶段发生error、timeout、指定HTTP状态码或invalid_header时触发重试,且依赖多节点upstream和合理健康检查机制。

Nginx 的 proxy_pass 本身不自动重试,重试行为完全依赖 proxy_next_upstream 及其配套参数的显式配置。它不是“请求失败就重发”,而是在特定失败阶段、满足条件时,才将请求转发给下一个 upstream 节点。
哪些失败会触发重试
只有在 proxy_pass 阶段发生以下几类错误时,Nginx 才可能启动重试:
- error:建连失败(如 Connection refused)、连接被重置、连接被拒绝等底层网络异常
-
timeout:包括
proxy_connect_timeout(建连超时)、proxy_send_timeout(发请求超时)、proxy_read_timeout(读响应头超时)——注意:读完整响应体不在此列 -
显式声明的状态码:默认不包含任何 HTTP 状态码;必须手动添加,例如
http_502 http_503 http_504;不建议加http_404或http_500,前者多是路径问题,后者常反映业务逻辑异常,重试无效甚至有害 -
invalid_header:后端返回空响应或非法响应头(如缺失
Status行、头字段格式错误)
重试的前提是有多节点可用
重试本质是 Failover,不是兜底补救。若 upstream 中只有一个 server,或所有节点都处于 fail 状态(比如因 max_fails 被临时剔除),则重试无从谈起。
- upstream 至少定义两个
server,并合理配置max_fails=2 fail_timeout=30s,使连续失败后自动隔离坏节点 - 被动健康检查靠失败累积触发;如需更早感知异常,需商业版或自编译模块支持主动健康检查(
health_check) - 重试过程不保证跳过已知坏节点——第一次仍可能打到刚宕机的 A,失败后才切到 B
控制重试范围与耗时边界
没有限制的重试等于不可控。关键参数需协同设置,避免逻辑冲突:
-
proxy_next_upstream_tries 3:最多尝试 3 次(含首次),不是“额外重试 2 次” -
proxy_next_upstream_timeout 30s:从第一次请求发出开始计时,总耗时超限即终止,返回最终错误(如 502) -
proxy_read_timeout 10s:等待后端响应头的上限;设太短会误判慢接口,设太长则用户等待过久 -
proxy_connect_timeout和proxy_send_timeout应同步调低(如均设为 3s),确保各阶段超时逻辑一致
避开常见副作用陷阱
重试不是万能药,用错反而引发严重问题:
-
非幂等操作禁用重试:POST 创建订单、支付回调等场景,绝不可配
non_idempotent,否则易造成重复写入;应由业务层通过唯一请求 ID + 幂等表控制 -
长耗时接口建议关闭重试:如报表生成、大文件导入,可单独用 location 隔离,配置
proxy_next_upstream off - 前端超时必须大于 Nginx 总重试窗口:否则用户侧已断开连接,Nginx 即便重试成功也无意义


















