proxy_next_upstream_tries设为3表示单次请求最多转发3次(含首次),非额外重试次数;必须配合timeout(如8s)和健康检查,否则高并发下易引发重试雪崩。

设 proxy_next_upstream_tries 为 3,不是为了“多试几次更稳”,而是给每次请求划一条硬性红线:最多转发 3 次(含首次),超了立刻放弃。它本身不防雪崩,但配错必引发雪崩——尤其在高并发下,无效重试会把压力复制 2–3 倍,直接拖垮后端集群。
明确 tries 是总次数,不是额外重试数
很多人误以为 tries 3 表示“失败后再重试 3 次”,实际是:第 1 次发给原始节点,失败后最多再换节点试 2 次,总共不超过 3 次请求。
- 设为 0(Nginx 默认)=无限重试,生产环境极度危险,必须显式覆盖
- 设为 1 =禁用重试,适合订单提交、支付回调等非幂等操作
- 设为 3 =最常用安全值,覆盖网络抖动、瞬时超时等常见故障
- 设为 ≥5,尤其 upstream 节点少于 3 台时,大概率反复打同一台已失联或假死的机器
必须绑定 proxy\_next\_upstream\_timeout 控制总耗时
只控次数不管时间,等于纵容长尾请求。timeout 是从第一次请求发出开始计时的**整体窗口**,超时即刻终止所有后续尝试并返回错误。
- 若单次合理响应在 2–4 秒,建议
proxy_next_upstream_timeout 8s(留出余量) - 若
proxy_read_timeout是 5 秒,timeout 不宜超过 12 秒,否则第三次尝试可能只剩不到 1 秒 -
tries=3但timeout=30s→ 前两次各卡 12 秒,第三次根本没机会执行 -
timeout=2s但tries=3→ 首次请求刚发就超时退出,重试形同虚设
重试前先剔除坏节点:健康检查不能缺位
proxy_next_upstream 是“出事才换人”,健康检查才是“提前把病人抬走”。没有后者,重试只是空转——Nginx 会不断把请求发给已失联或假死的节点。
- 启用主动探测:
health_check interval=3 fails=2 passes=2 -
check_http_expect_alive只认 2xx/3xx,避免把返回 200 的假健康接口当真 - 搭配被动策略:
max_fails=2 fail_timeout=30s,让偶发失败也能快速下线节点 - 避免
health_check间隔 >10s 或fails ≥5,否则宕机节点会长期滞留
按请求语义决定是否允许重试
重试本质是风险放大器。高并发下一次失败后立刻转给另一台机器,等于把压力复制 2–3 倍。
- GET 类查询可谨慎开启:
proxy_next_upstream error timeout http_502 http_503 http_504 - POST/PUT/DELETE 默认不重试;强行加
non_idempotent必须由业务层 100% 保障幂等(如带唯一请求 ID + 服务端去重) - 绝对不要加
http_404、http_403、http_500——它们多属业务错误,重试无意义,还可能重复扣款或生成重复订单











