proxy_next_upstream_tries设为3表示单次请求最多转发3次(含首次),必须与proxy_next_upstream_timeout、健康检查及可恢复错误触发条件协同生效,单独设置无效。

避免因 proxy_next_upstream 盲目重试引发后端雪崩,核心是不让重试行为失控——它必须有明确的次数上限、严格的时间封顶、真实的节点可用性依据,且只对可恢复错误生效。设了参数不联动,等于没设。
限制总尝试次数,明确“最多发几次”
proxy_next_upstream_tries 是单次请求的总转发上限(含首次),不是“失败后再试 N 次”。生产环境最稳妥的值是 3:第 1 次原发 + 最多再换 2 个节点重试。常见误区要避开:
- 设为 0(Nginx 默认)=无限重试,高并发下极易把压力复制到所有节点,直接拖垮集群
- 设为 1=禁用重试,适合支付回调、订单创建等非幂等操作
- 设为 ≥5,尤其 upstream 节点少于 3 台时,大概率反复打同一台已失联或假死机器
绑定总耗时窗口,堵住长尾等待
proxy_next_upstream_timeout 是从第一次请求发出开始计时的**整体时间上限**,超时即刻终止全部尝试并返回 502。它和 tries 必须咬合:
- 若
proxy_read_timeout是 5s,建议proxy_next_upstream_timeout设为 8–10s(留出网络调度与切换余量) - 设
tries 3却配timeout 30s→ 前两次各卡 12s,第三次根本来不及执行 - 设
timeout 2s却配tries 3→ 首次请求刚发就超时退出,重试形同虚设
只对真正可恢复的错误重试
重试不是兜底万能键。加错状态码会把业务错误也放大,造成重复扣款、双订单等严重后果:
- 最小安全集:
error timeout(连接失败、响应超时) - 确认上游稳定且幂等后,可谨慎加:
http_502 http_503 http_504 - 绝对不要加:
http_404 http_403 http_500—— 它们代表资源不存在、权限不足或后端逻辑异常,重试无意义 - POST/PUT/DELETE 默认不重试;强行启用
non_idempotent,必须由后端 100% 保障幂等(如基于唯一 request_id + Redis 去重)
健康检查必须到位,否则重试只是空转
proxy_next_upstream 是被动容错(出事才换人),没有健康检查,Nginx 就不知道谁已经挂了,重试只会不断打向故障节点:
- 启用主动探测:
health_check interval=3 fails=2 passes=2;,每 3 秒探测一次,连续 2 次失败即剔除 -
check_http_expect_alive只认2xx/3xx,避免把返回 200 的空 /health 接口当真 - 搭配被动机制:
max_fails=2 fail_timeout=30s,让偶发抖动不误踢,连续失败快速隔离 - 健康检查间隔别大于 10s,否则宕机节点会长期滞留参与流量分发











