Nginx中error_page可捕获limit_req触发的503错误并重定向,需将limit_req置于location块内、配置error_page 503指向独立不受限流约束的内部location或页面,避免循环;nodelay会加速503返回,利于捕获。

在 Nginx 中,error_page 本身不能直接捕获限流(rate limiting)触发的错误,因为限流由 limit_req 模块主动拒绝请求时返回的是 503 Service Temporarily Unavailable,而这个状态码可以被 error_page 拦截并重定向 —— 关键在于正确配置限流和错误页面的联动。
确保限流触发 503 状态码
Nginx 的 limit_req 默认在超出速率限制时返回 503。但需确认未显式修改为其他行为(如 burst + nodelay 可能暂存请求,不立即报错)。标准限流配置示例如下:
- 定义限流区域:
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s; - 在 location 中启用限流:
limit_req zone=api burst=10 nodelay;(注意:若用nodelay,突发请求可能不排队而是直接拒绝,更易触发 503) - 不加
nodelay时,超限请求会排队等待;排队超时(默认 1 秒)后才返回 503,此时仍可被捕获
用 error_page 捕获 503 并重定向
在对应作用域(server 或 location)中添加 error_page 指令,将 503 重定向到自定义路径或外部 URL:
- 重定向到站内提示页:
error_page 503 /rate-limited.html;,并确保该路径有对应的location = /rate-limited.html { ... }处理 - 重定向到外部地址:
error_page 503 =302 https://example.com/too-many-requests;(注意=302表示返回 302 状态码,而非内部跳转) - 若需保留原始请求方法(如 POST),避免用 302(会变 GET),改用 307:
error_page 503 =307 /fallback;
避免循环和权限问题
重定向目标路径本身不能受相同限流规则约束,否则会陷入无限重定向或持续返回 503:
- 把限流规则放在特定 location(如
/api/),而/rate-limited.html或/fallback单独配置,且不套用limit_req - 检查重定向目标是否被其他模块拦截(如 auth_basic、deny 等),确保能正常访问
- 使用
log_not_found off;可防止 503 重定向失败时大量记录 “file not found” 日志
验证与调试技巧
限流 + error_page 是否生效,可通过 curl 和日志快速验证:
- 用脚本快速触发限流:
for i in {1..10}; do curl -I http://localhost/api/test; done,观察响应头中是否出现HTTP/1.1 503或重定向后的状态码 - 开启 Nginx 错误日志:
error_log /var/log/nginx/error.log debug;,搜索limiting requests和error_page相关条目 - 注意:若用了
proxy_intercept_errors on;(常见于反向代理场景),它会影响 error_page 行为,确保该指令未意外关闭错误页面处理


















