proxy_intercept_errors需与error_page同location块配合使用,仅对proxy_pass代理响应生效,通过internal命名location实现统一降级,且须注意响应体长度、状态码识别及upstream分组差异化处理。

在 Nginx 负载均衡场景下,proxy_intercept_errors 不是独立生效的“拦截器”,而是和 error_page 协同工作的开关——它只在 proxy_pass 代理到 upstream 的 location 中启用,且必须与 error_page 同作用域,才能让 Nginx 拦住后端返回的 4xx/5xx 错误并统一降级。
必须在同一 location 块中成对配置
负载均衡的核心是 upstream + proxy_pass,而错误拦截逻辑必须落在这个代理块里:
-
proxy_intercept_errors on;写在location /api { ... }内,不能只放在 server 或 http 块(不继承) - 紧跟着写
error_page 500 502 503 504 = @degrade;,用命名 location 实现内部跳转 -
proxy_pass http://my_upstream;必须也在同一 location 中,否则指令不生效
定义 internal 命名 location 处理降级响应
被 error_page 指向的命名 location 必须设为 internal,防止用户绕过代理直接访问:
location @degrade { internal; return 500 '{"code":500,"msg":"service unavailable"}'; }- 若需返回静态 HTML,改用:
location @degrade { internal; root /usr/share/nginx/html; try_files /degrade.html =404; } - 不要用
error_page 502 /degrade.html直接路径跳转——容易因 root 配置错位导致二次 404
确保后端错误能被真正拦截
Nginx 默认只拦截响应体非空且状态码 ≥400 的响应,负载均衡中常见失效点:
- 后端返回精简错误(如纯文本 "Bad Gateway"),长度不足默认阈值(512 字节)→ 可加
proxy_buffering off;强制识别 - 后端返回 200 + JSON 里带
"error": "timeout"→proxy_intercept_errors完全不触发,它只看 HTTP 状态码 - upstream 中某节点宕机,Nginx 自动返回 503(健康检查失败)→ 此类 503 仍可被拦截,只要配置了
error_page 503
按 upstream 分组做差异化降级(进阶)
不同业务后端故障语义不同,可用 map 结合变量实现动态响应:
- 先定义映射:
map $upstream_addr $degrade_code { ~10\.0\.1\.10:8080 503; ~10\.0\.1\.11:8080 429; default 500; } - 在 location 中引用:
error_page 500 502 503 504 = $degrade_code @degrade; - 再在
@degrade中用return $degrade_code ...返回对应状态码与内容


















