必须显式配置proxy_next_upstream error timeout http_502并设tries和timeout,配合max_fails健康检查及至少两个上游节点,才能在后端返回502时自动重试;否则nginx默认直接返回错误。

遇到后端返回 502,Nginx 轮询本身不会自动重试——必须显式配置触发条件和重试边界,否则请求就卡在故障节点上,用户直接看到错误。
必须开启 proxy_next_upstream 并明确包含 http_502
仅靠轮询机制无法感知 502,Nginx 默认把它当作最终响应返回给客户端。要让它“换一台再试”,得在 location 或 server 块中写:
- proxy_next_upstream error timeout http_502; ——http_502 是关键项,不能省略;error 覆盖连接拒绝、收响应头失败等底层异常,timeout 覆盖建连/读写超时
- 没有 http_502,即使后端真返回了 502 状态码,Nginx 也不会重试
- 注意:502 是上游返回的 HTTP 状态码,不是 Nginx 自己生成的;如果后端崩溃导致空响应或连接重置,那属于 error 或 timeout 场景,也要靠对应关键字覆盖
限制重试次数和总耗时,防雪崩
不加约束的重试会让延迟翻倍、压力叠加。需同步配置:
- proxy_next_upstream_tries 3; ——最多尝试 3 次(含首次),即最多打到 3 台不同后端
- proxy_next_upstream_timeout 10s; ——整个重试过程从第一次发出请求开始计时,超时即返回错误,不无限等待
- 这两个值要匹配业务容忍度:比如核心接口可设为 tries=2 timeout=5s,后台任务可放宽
搭配 max_fails 做被动健康剔除
光重试不够,得让 Nginx 记住“这台不行”,避免下次还选它:
- 在 upstream 的 server 行里加:max_fails=2 fail_timeout=30s;
- 只要该节点在 30 秒内因 error/timeout/http_502 失败 2 次,就被标记为 down,30 秒内不再参与轮询
- fail_timeout 到期后会自动试探一次,成功则恢复;失败则继续下线
- 至少要有 2 个正常 upstream 节点,否则重试和熔断都失效
用 proxy_intercept_errors 统一兜底体验
当所有可用后端都重试失败,最终还是要给用户一个友好反馈:
- 在 location 块中启用:proxy_intercept_errors on;(不能放在 http 或 server 级)
- 定义错误页:error_page 502 503 504 /error.html;
- 再配一个 location = /error.html { root /usr/share/nginx/html; },确保页面能正确加载且 MIME 类型识别为 text/html











