最直接有效的方式是启用 rewrite_log 指令并配合 error_log 的 notice 或更高级别,但仅限调试编译版 Nginx;需先用 nginx -V 检查 with-debug,再在配置中添加 rewrite_log on 和 error_log ... notice,日志中连续匹配同一规则且 URI 不断增长即表明死循环。

在 Nginx 中排查重写(rewrite)导致的死循环,最直接有效的方式是启用 rewrite_log 指令,并配合 error_log 的调试级别使用。注意:该功能仅在调试编译版(即带 --with-debug)的 Nginx 中可用,常规发行版(如 Ubuntu/Debian 官方包、CentOS Stream 的 nginx)默认不包含 debug 日志支持。
确认 Nginx 是否支持 rewrite_log
执行以下命令检查是否启用了 debug 支持:
nginx -V 2>&1 | grep -o with-debug
若无输出,说明当前 Nginx 不支持 rewrite_log,需重新编译或改用其他方式(如添加临时 return / echo 日志)。
在 nginx.conf 中启用重写日志
在 http、server 或 location 块中添加:
rewrite_log on;
error_log /var/log/nginx/rewrite.log notice;
⚠️ 关键点:
-
rewrite_log on必须配合error_log ... notice或更高级别(如info、debug)才生效;设为warn或更高(如error)将看不到 rewrite 日志 - 推荐先用
notice级别,避免日志爆炸;确认有循环后再切到info获取更详细匹配路径 - 日志文件路径需确保 Nginx 工作进程(通常是
www-data或nginx用户)有写权限
典型死循环 rewrite 场景与日志识别
例如配置了如下易错规则:
location / {
rewrite ^/(.*)$ /index.php?path=$1 last;
}
访问 /index.php 时可能反复匹配、跳转,造成 500 或超时。开启日志后,你会在 rewrite.log 中看到类似行:
2024/05/20 14:22:33 [notice] 12345#12345: *1 "^(.*)$" matches "/index.php", client: 127.0.0.1, server: example.com, request: "GET /index.php HTTP/1.1", host: "example.com"
2024/05/20 14:22:33 [notice] 12345#12345: *1 rewritten data: "/index.php?path=index.php"
2024/05/20 14:22:33 [notice] 12345#12345: *1 "^(.*)$" matches "/index.php?path=index.php", client: 127.0.0.1, ...
连续多条“matches”且 URI 越变越长(如出现 ?path=index.php?path=...),基本可判定为死循环。
安全关闭与替代方案
调试完成后务必关闭,因为 rewrite 日志开销大、易填满磁盘:
- 注释或删除
rewrite_log on - 将
error_log级别调回error或warn - 如无法编译 debug 版,可用
return 200 "DEBUG: $request_uri → $args";插入关键 location 中人工观察跳转链
不复杂但容易忽略:rewrite_log 不是独立日志模块,它完全依赖 debug 编译和 error_log 级别协同生效。


















