轮询需配合proxy_next_upstream及超时参数才能实现自动重试:必须同时配置proxy_connect_timeout、proxy_read_timeout和proxy_next_upstream,并结合max_fails/fail_timeout健康检查,且注意http版本、指令位置及语法正确性。

轮询本身不带重试能力,必须手动配置 proxy_next_upstream 及配套超时参数,才能在后端失败时自动换节点重发请求,避免用户收到错误响应。
必须设置的三项重试基础参数
仅靠轮询无法应对临时故障。以下三者需同时存在,缺一不可:
-
连接超时:用
proxy_connect_timeout 3s;控制建立 TCP 连接的等待上限,防止卡在不可达节点 -
响应超时:用
proxy_read_timeout 10s;限制等待后端返回完整响应的时间,避免长尾拖慢整体 -
触发重试的条件:通过
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;明确哪些状态要换节点重试
健康检查要与重试联动才有效
重试不是无限制乱跳,Nginx 会结合每个 server 的健康状态做判断:
- 每台 server 后需加
max_fails=3 fail_timeout=30s;,连续失败 3 次后暂停调度 30 秒 - 重试时,Nginx 会跳过已被标记为 “down” 的节点,只在当前健康的节点中轮询重试
- 若所有节点都处于 fail_timeout 状态,Nginx 会 fallback 到最近一次成功响应过的节点(即使它刚被标记为 down),避免彻底中断
避免重试失效的常见配置陷阱
很多重试配置看似写了,实则未生效,问题多出在细节:
- 没写
proxy_http_version 1.1;和proxy_set_header Connection '';,导致连接无法复用,每次重试都新建 TCP 连接,放大延迟 -
proxy_next_upstream放在 upstream 块里——它只在 location 或 server 块中生效 - 用了
ip_hash或least_conn等策略,轮询逻辑已失效,重试行为可能偏离预期 - server 行漏写分号或 weight 写错位置,导致语法错误,整个 upstream 加载失败,重试根本不会启动
验证重试是否真正起作用
不要只看配置,要观察真实行为:
- 停掉其中一台后端,用
curl -I http://nginx-host/api/test连续请求 5 次,确认全部返回 200,且$upstream_addr日志中不出现已停机的 IP - 故意让某台后端返回 502,观察 Nginx access log 中该请求是否只记一次(说明重试内部完成),而不是返回 502 给客户端
- 查看 Nginx error log,出现
upstream timed out或no live upstreams提示,说明重试机制正在工作而非静默失败











