error_page 与命名 location 配合实现后端降级的核心是将错误拦截作为控制跳转点,由命名 location 承担备用服务调用、兜底渲染或动态决策等逻辑;需置于 proxy_pass 同级 location 或 server 块,配合 proxy_intercept_errors on 生效,并用 = @name 触发内部跳转。

要让 error_page 和命名 location 配合实现灵活的后端降级逻辑,核心不是简单返回静态页,而是把错误拦截当作一个“控制跳转点”,再由命名 location 承担具体业务逻辑——比如调用备用服务、渲染兜底内容、甚至动态判断是否启用降级。
明确 error_page 的触发条件与作用域
error_page 必须放在能捕获到错误的位置。常见误区是把它写在 http 块或错误的 location 里。正确做法是:
- 对 API 接口,把 error_page 放在 proxy_pass 所在的 location 内(如 location /api/ { ... })
- 若需统一处理所有后端错误,可放在 server 块中,但要注意它不会自动生效于子 location,除非子 location 没有覆盖
- proxy_intercept_errors on 是前提——没有它,Nginx 会直接透传 502/504 给客户端,根本不会触发 error_page
用命名 location 封装可复用的降级行为
命名 location(以 @ 开头)不响应外部请求,只供内部跳转,适合做逻辑容器。例如:
- @fallback_static:返回预置 HTML,配合 try_files + index 实现零状态码报错
- @fallback_api:proxy_pass 到另一个更稳定的后端集群,做服务级降级
- @fallback_dynamic:转发给本地 FastCGI 或 Lua 脚本,根据请求头、时间、错误类型等做决策
每个命名 location 都应加 internal;,避免被恶意直连;root 或 alias 要显式指定,防止路径拼接出错。
组合 try_files + error_page + 命名 location 构建多层兜底
典型链路:静态资源 → 后端服务 → 错误拦截 → 降级页 → 备用接口 → 最终兜底。配置示例:
- 先用 try_files 尝试本地缓存文件:try_files /cache/$uri $uri @backend;
- 在 @backend 中 proxy_pass 并开启拦截:proxy_intercept_errors on; error_page 500 502 503 504 @degrade;
- @degrade 内部可再分层:try_files /degrade/maint.html @backup_api;
- @backup_api 可 proxy_pass 到灾备集群,失败后再 fallback 到最终静态页
保留或覆盖原始状态码的关键细节
用户看到什么状态码,取决于 error_page 后面有没有等号(=):
- error_page 502 /50x.html:返回 502 状态码,内容是 /50x.html —— 适合运维监控识别问题
- error_page 502 = /50x.html:返回 200 状态码,内容是 /50x.html —— 适合前端 SPA 不因状态码中断路由
- error_page 502 =502 /50x.html:显式返回 502,内容是 /50x.html —— 更清晰可控
- 如果用命名 location(如 @fallback),必须搭配 = @fallback,否则 Nginx 不知道该走内部重定向还是外部跳转
不复杂但容易忽略。

















