一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Nginx 如何排查 Nginx 配置文件中 Rewrite 规则编写错误导致的死循环故障

时间:2026-08-16 12:18:49 编辑:袖梨 来源:一聚教程网

Rewrite死循环表现为访问卡顿、浏览器报重定向过多或500错误,access.log刷屏;核心线索是error_log中“rewrite or internal redirection cycle”提示及反复跳转的URI路径。

遇到 Rewrite 死循环,最直接的表现是访问瞬间卡住、浏览器报“重定向次数过多”,或服务端返回 500 错误,同时 access.log 疯狂刷屏、磁盘空间几秒内告急。这不是日志配置问题,而是请求在 Nginx 内部不断自我重写——关键要从现象反推路径链,再结合配置逻辑验证。

看 error_log 抓核心错误线索

Nginx 在检测到内部跳转超限(默认 10 次)时,一定会在 error.log 中记录明确提示:

  1. 搜索 rewrite or internal redirection cycle —— 这是死循环的铁证
  2. 紧接其后的 internally redirecting to "/xxx" 显示最终卡住的 URI,比如 /index.php/api/user
  3. 再往上翻几行,找到 client: xxx, server: xxx, request: "GET /xxx HTTP/1.1",确认原始触发路径

注意:很多“循环”其实是假象。继续往下查,如果看到 Permission deniedNo such file or directory,说明目标文件不可读或根本不存在,Nginx 因 fallback 失败反复尝试,也会表现为循环。

用 curl -I 快速模拟跳转行为

不依赖日志,直接观察响应头是否来回跳:

  1. 执行 curl -I http://your-domain/some-path
  2. 若返回多个 Location: https://... 且地址在两个值之间反复切换(如 A→B→A→B),说明 rewrite 已形成闭环
  3. 特别注意 permanent(301)和 redirect(302)标志,它们会让浏览器持续重发请求,放大问题

启用 debug 日志看清每一步改写

普通 error log 只报结果,debug 日志才能还原完整路径链:

  1. nginx.confhttp 块中临时添加:

    error_log /var/log/nginx/debug.log debug;

  2. 确保 Nginx 编译时启用了 --with-debug(主流发行版通常默认支持)
  3. 重启后复现请求,执行:

    sudo tail -f /var/log/nginx/debug.log | grep -E "(rewrite|redirect|phase)"

  4. 你会看到类似:

    *123456 rewrite phase: 3, "/old/test" -> "/new/test"

    *123456 rewrite phase: 3, "/new/test" -> "/old/test" —— 跳转链一目了然

检查 rewrite flag 与 location 匹配范围是否冲突

死循环高频发生于 last 和宽泛 location 的组合:

  1. last 表示重写后重新走一遍全部 location 匹配流程;若新 URI 仍落入当前 location 范围,就会再次触发 rewrite
  2. 典型错误:location /a/ { rewrite ^/a/(.*)$ /a/$1 last; } —— 改写前后都在 /a/ 下,必然循环
  3. 正确做法:

    • 改用 break(改写后留在当前 location 继续执行,不重匹配)

    • 或收紧 location,如 location ^~ /a/ + 改写目标为 /b/$1

    • 或优先用 return 301 替代 rewrite 实现外部跳转

热门栏目