nginx 不主动处理后端状态码,需通过 proxy_next_upstream 等指令按语义区分重试(如 503/504)、降级(如 error_page 跳转备用 upstream)、转换(如 500 转 503)或兜底(如缓存返回),核心是精准识别错误类型并配置最小安全集。

Nginx 对后端返回的状态码本身不主动“处理”,而是通过配置决定是否重试、降级、转换或兜底。关键不是状态码本身,而是你对它的语义判断和后续动作设计。
区分可重试与不可重试错误是核心前提
503、504 属于临时性故障,换节点大概率成功;500 多为业务逻辑崩溃,重试可能无效甚至加重问题;404 是确定性结果,重试毫无意义。不能把所有 5xx 当作一类来配置。
用 proxy_next_upstream 精确控制重试触发条件
该指令必须显式声明哪些状态码能触发重试,默认不响应任何 HTTP 状态码。推荐最小安全集:
-
error timeout http_503 http_504 - 谨慎加入
http_500(仅当确认是瞬时资源争用且多活部署可靠) - 避免
http_404、http_400等确定性错误
同时配合:
-
proxy_next_upstream_tries 2(最多尝试 2 次,含首次) -
proxy_next_upstream_timeout 8s(整个重试流程限时)
用多个 upstream 分组实现按错误类型分流
单一 upstream 无法差异化响应。可定义语义化分组:
- 主源组:
upstream origin_main { server a.example.com max_fails=2 fail_timeout=5s; } - 5xx 备用组:
upstream origin_5xx_fallback { server b.example.com backup; }
再结合error_page实现定向跳转:error_page 503 504 = @retry_5xx; location @retry_5xx { proxy_pass http://origin_5xx_fallback; }
用 error_page + return 或 proxy_cache_use_stale 做语义转换与兜底
- 把上游 500 统一转为 503 并返回结构化 JSON:
error_page 500 =503 @handle_500; location @handle_500 { default_type application/json; return 503 '{"code":"SERVICE_UNAVAILABLE","message":"Try again later"}'; } - 对静态路径的 503 直接返回过期缓存:
error_page 503 = @stale_fallback; location @stale_fallback { proxy_cache_use_stale error timeout updating; proxy_pass http://origin_main; }
不复杂但容易忽略











