Nginx 的 error_page 指令通过拦截特定 HTTP 状态码(如 502/503 或自定义 451)实现路径级降级,需配合 proxy_intercept_errors、return 触发或 try_files 静态兜底,并用 internal 保护降级页。

Nginx 的 error_page 指令本身不直接判断“特定路径故障”,而是响应 HTTP 状态码。要实现“某路径出错时返回降级页面”,核心思路是:让该路径在异常时主动返回一个可被捕获的状态码(如 502、503 或自定义的 418/451),再用 error_page 将其重定向到本地静态降级页。
1. 为特定 location 配置错误捕获与重定向
在对应 location 块中,使用 proxy_intercept_errors on(若后端是 proxy)或配合 return/fastcgi_intercept_errors 主动触发错误状态,再通过 error_page 拦截处理:
- 反向代理场景(推荐):后端挂掉时默认返回 502/503,开启拦截并重定向
location /api/v1/user {
proxy_pass http://backend;
proxy_intercept_errors on; # 允许拦截 5xx 错误
error_page 502 503 504 /fallback/user-down.html;
}
<p>location = /fallback/user-down.html {
internal; # 仅限内部重定向访问,禁止外部直连
root /usr/share/nginx/html;
}</p>-
主动触发降级(更可控):用
if+return模拟故障条件(如健康检查失败、变量标记)
set $downstream_ok "1";
# 可通过 external config、lua、或 upstream health check 设置 $downstream_ok
<p>location /api/v1/order {
if ($downstream_ok = "0") {
return 503;
}
proxy_pass <a href="https://www.php.cn/link/ac68bc93ecc07d7daec8ce924ca09b0c">https://www.php.cn/link/ac68bc93ecc07d7daec8ce924ca09b0c</a>;
proxy_intercept_errors on;
error_page 503 /fallback/order-unavailable.html;
}</p>2. 使用自定义状态码避免干扰正常错误流
为避免和真实服务错误混淆,可定义专属降级码(如 451 表示“临时不可用”),并在 error_page 中显式声明:
- 在 location 中用
return 451触发降级逻辑 - 全局或 server 块中声明:
error_page 451 /fallback/maintenance.html; - 确保
/fallback/maintenance.html用internal保护,且路径存在
3. 配合 try_files 实现静态兜底(轻量级替代方案)
若降级页本身就是静态资源,且希望绕过状态码机制,可用 try_files 直接 fallback:
location /status/live {
# 优先尝试健康检查接口,失败则返回本地静态页
try_files /dev/shm/healthz @fallback;
<pre class="brush:php;toolbar:false;"># 若 /dev/shm/healthz 不存在或返回非200,跳转到 @fallback
}
location @fallback { return 200 '{"status":"degraded","time":'$(date +%s)''; add_header Content-Type application/json; }
注意:try_files 判断的是文件是否存在或 upstream 返回是否为成功状态(取决于配置),适合简单场景,但不如 error_page 灵活支持多状态码分级降级。
4. 注意事项与常见陷阱
-
error_page是**内部重定向**,目标 location 必须加internal,否则可能被外部请求直接访问 -
proxy_intercept_errors on仅对 proxy_pass 生效;FastCGI 需配fastcgi_intercept_errors on - 不要在
error_page后写proxy_pass到另一个可能失败的上游——这会引发嵌套错误,建议降级页必须是本地静态资源或极简响应 - 日志中仍会记录原始错误(如 502),可在降级 location 中用
access_log off避免噪音










