Nginx默认不重试500,需显式配置proxy_next_upstream error timeout http_500,并配合tries、timeout、健康检查等限制范围与条件,仅适用于瞬时资源争用场景。

Nginx 默认不会对后端返回的 500 状态码自动重试,必须显式启用并谨慎配置。是否重试 500 取决于业务场景——若确认是瞬时资源争用(如数据库连接池满、线程阻塞),且其他节点大概率可用,才适合开启;若 500 源于代码异常或逻辑崩溃,则重试无效甚至有害。
启用 500 重试需显式声明
在 location 或 upstream 块中添加以下指令:
-
proxy_next_upstream error timeout http_500;—— 注意必须写http_500,不能写500或http/500 - 仅当后端真实返回 HTTP 状态行
HTTP/1.1 500 Internal Server Error时才触发,不识别响应体中的业务错误码(如 JSON 里"code":500) - 默认不包含任何 5xx,
http_500必须手动加入,否则即使返回 500 也直接透传给客户端
限制重试范围,避免雪崩
单独开启 http_500 不够,还需控制次数与超时:
-
proxy_next_upstream_tries 2;—— 最多尝试 2 台服务器(含首次),防止轮询全部节点 -
proxy_next_upstream_timeout 10s;—— 所有重试总耗时上限,超时即终止并返回最终错误 - 确保
upstream至少定义两个活跃节点,否则无“下一节点”可选
配合健康检查形成闭环
重试有效依赖上游节点状态感知:
- 在
upstream中设置max_fails=2 fail_timeout=30s;,让 Nginx 主动标记不可用节点 - 重试时自动跳过已失败节点,只在当前认为“健康”的节点中轮询
- 避免把请求发给刚返回 500 的同一台机器(除非它尚未被标记为失败)
区分场景:慎用 vs 可用
不是所有 500 都适合重试:
- ✅ 推荐重试:源站因临时资源不足(如 CPU 突增、DB 连接池耗尽)返回 500,且部署为多活架构
- ❌ 禁止重试:500 来自未捕获异常、配置错误或单点故障,重试只会放大延迟和负载
- ⚠️ 替代方案:对确定性 500,用
error_page 500 = @fallback;跳转至降级逻辑(如返回缓存、静态页或 JSON 提示)


















