重试组即配置了多节点与容错策略的upstream块,是proxy_next_upstream实现自动切换的前提;需至少2台活跃server、显式声明error/timeout/502-504等触发条件,并配合tries和timeout限流,才能安全生效。
Nginx 的 proxy_pass 本身不直接提供“重试组”功能,真正实现后端服务器自动切换与重试的是 upstream 块配合 proxy_next_upstream 系列指令。所谓“重试组”,实际指的就是一个定义了多个后端节点、并配置了容错策略的 upstream 分组——它才是重试机制的载体。
upstream 块定义了一组可被 proxy_pass 引用的后端服务器,是重试的前提:
upstream backend_cluster { server 10.0.1.10:8080 max_fails=2 fail_timeout=30s; server 10.0.1.11:8080 max_fails=2 fail_timeout=30s; server 10.0.1.12:8080 backup; # 备用节点,仅当主节点全不可用时启用}
max_fails 和 fail_timeout 构成被动健康检查:某节点连续失败指定次数后,在 fail_timeout 内不再参与调度;backup 节点不参与常规轮询,只在所有非 backup 节点都不可用时才启用。proxy_pass 指令引用 upstream 名称,而非直接写地址:
location /api/ { proxy_pass http://backend_cluster; # 注意:不带 /,且不能加路径 proxy_next_upstream error timeout http_502 http_503 http_504; proxy_next_upstream_tries 3; proxy_next_upstream_timeout 15s;}
关键点:
proxy_pass http://backend_cluster 中的 backend_cluster 必须与 upstream 名称完全一致;/api/ 或 /),否则语法错误或行为异常;location ~ ^/v1/),proxy_pass 后也严禁带 URI,必须靠 rewrite + break 控制路径。默认只对 error(连接失败、被拒、断连)和 timeout(建连/发请求/读响应头超时)重试。常见 HTTP 错误码不会自动重试,需手动加入:
✅ 推荐组合(安全、通用):
error:网络层失败(如 connection refused)timeout:各阶段超时http_502 / http_503 / http_504:网关类错误,通常表示后端临时不可用❌ 避免加入:
http_404:路径不存在,换节点大概率还是 404;http_500:服务内部异常,可能状态不一致,重试可能放大问题;non_idempotent:允许对 POST/PUT 等非幂等请求重试,极易造成重复提交(如下单、扣库存),生产环境禁用。重试不是无限循环,必须用两个参数框定安全窗口:
proxy_next_upstream_timeout 15s:从第一次请求发起开始计时,总耗时上限(含网络延迟、重试间隔、后端响应时间);proxy_next_upstream_tries 3:最多尝试 3 个 server(含首次),不是“额外重试 2 次”;配套建议:
proxy_read_timeout 10s:等待后端响应头的上限,应 ≤ proxy_next_upstream_timeout;proxy_connect_timeout 3s 和 proxy_send_timeout 5s 也要同步设小,避免某阶段卡死拖垮整体重试窗口。假设 upstream 定义 A/B/C 三台,A 突然宕机:
error)→ 触发重试;tries=3 未超限、timeout=15s 未超 → 切到 B 发起新请求;max_fails 计数+1,若达 2 次,则未来 30 秒内不再被选中。整个过程对用户透明,前提是 upstream 有冗余、配置无遗漏、超时逻辑对齐。