proxy_next_upstream 本身仅定义重试触发条件(如 error、timeout、http_502/503/504),必须配合 upstream 中的 max_fails/fail_timeout 实现节点健康判定,并依赖多节点列表与幂等性约束(默认仅重试 GET)才能完成可靠故障转移。

直接配置 proxy_next_upstream 本身并不能“自动重试其他节点”,它只是告诉 Nginx 在什么条件下触发重试;真正实现故障转移,需要和 upstream 块中的健康判定机制(如 max_fails、fail_timeout)以及后端服务器列表配合使用。关键不是加了这个指令就万事大吉,而是要理解它和上游状态管理的联动逻辑。
明确哪些响应会触发重试
该指令定义在 location 或 server 块中,用于指定在遇到哪些情况时,Nginx 放弃当前 upstream server,转向下一个可用节点重试请求:
-
超时类:
error(连接失败)、timeout(代理连接或读取超时) -
响应类:
http_500、http_502、http_503、http_504(常见网关错误);注意:http_404默认不重试,除非显式加上 -
可选但慎用:
invalid_header(后端返回非法响应头)、off(完全禁用重试)
典型写法:proxy_next_upstream error timeout http_502 http_503 http_504;
必须搭配 upstream 的失败判定机制
仅设重试条件还不够。Nginx 需要知道“哪台后端算故障”,这由 upstream 块里的参数控制:
-
max_fails=1表示只要失败 1 次,就标记该 server 为不可用(太敏感,易误判) -
fail_timeout=10s表示被标记后,10 秒内不再分发请求给它 - 若你同时设置了
proxy_next_upstream_tries=3,但max_fails=1,那三次重试很可能全打在同一台刚被标记为“不可用”的 server 上——等于没重试
合理组合示例:
upstream backend {<br>
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;<br>
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;<br>
}
GET 和 POST 的重试行为有本质区别
Nginx 默认只对幂等方法(主要是 GET)重试。即使你配置了 proxy_next_upstream ... http_502,POST 请求在遇到 502 时通常不会重试——因为重复提交可能引发数据重复(如重复下单)。这点必须清楚:
- 如果你的业务接口是 POST 且要求高可用,不能依赖 Nginx 自动重试,得靠后端服务自身做幂等或客户端重试
- 强行对 POST 开启重试(如加
non_idempotent)风险极高,不推荐
别忘了主动健康检查才是稳定基础
开源 Nginx 不支持内置主动健康检查,这意味着:一旦某台后端因慢响应被 max_fails 标记为不可用,它只能靠 fail_timeout 被动等待恢复。如果后端卡住 20 秒,而 fail_timeout 是 10 秒,它会在恢复前就被反复踢出又踢入,造成抖动。
解决办法:
- 引入第三方模块如
nginx-upstream-check-module,定期探测/health接口 - 或迁移到支持主动探活的网关(如 Nginx Plus、Traefik、Envoy)


















