要让proxy_next_upstream真正实现故障平滑切换,必须协同配置四要素:明确失败类型(如error、timeout、http_502-504)、限制重试边界(proxy_next_upstream_tries与timeout成对设置)、启用被动健康检查(max_fails/fail_timeout)、严守幂等原则(仅对GET/HEAD默认重试,非幂等请求需上游完全幂等才可谨慎开启)。
要让 proxy_next_upstream 真正实现故障平滑切换,不是加一行指令就完事,而是得让它“知道什么算失败”“往哪切”“切几次”“切多久”,同时避开非幂等请求的陷阱。
默认情况下,Nginx 只对 error(连接失败)和 timeout(超时)重试,对后端返回的 502/503/504 等网关错误并不自动处理。必须显式列出才生效:
error timeout——覆盖建连失败、响应卡死等底层异常http_502 http_503 http_504——这类错误常因后端过载或进程崩溃导致,换节点大概率成功invalid_header——防后端返回空响应、PHP 错误页或缺失 Status 行等“假存活”状态http_404、http_403、http_500——前两者是路径或权限问题,后者多为业务逻辑错误,重试无意义,还可能引发重复下单、扣费这两个参数必须成对设置,否则容易拖慢请求或引发雪崩:
proxy_next_upstream_tries 3:最多尝试 3 个不同节点(含首次),不是“额外重试 3 次”。若 upstream 有 2 台主节点,设为 3 是合理上限proxy_next_upstream_timeout 10s:从第一次请求发出开始计时,整个重试流程总耗时不能超 10 秒。它应 ≥ 单次 proxy_read_timeout(如设为 5s),但不宜过大——否则用户可能长时间等待却无响应proxy_next_upstream 是“失败后兜底”,不是“提前规避”。没有健康检查,Nginx 仍会轮询已宕机但未标记的节点,导致每次请求都先失败再重试:
upstream 的每个 server 后加 max_fails=3 fail_timeout=30s:连续 3 次失败(包括重试触发的 502/504)后,该节点 30 秒内不再参与调度backup 节点:仅当所有主节点都被标记为 down 时才启用,适合灾备或降级服务upstream_check_module):health_check interval=3 fails=2 passes=2,比被动等待更快发现故障重试本质是重复发请求,安全的前提是“重复执行无副作用”: