这个坑值得记一笔。CentOS 7.9 的 PHP 站点改成了 pathinfo 路由,加了 try_files 之后首页能开,点进详情页直接 500,错误日志写 rewrite or internal redirection cycle while internally redirecting to /index.php。

刚开始盯着「rewrite 的 last 标志触发了新的一轮匹配,规则没有终止条件」,折腾了半个多小时,排掉了。

把日志和配置对完,能解释这个现象的基本就这几处。try_files 的最后一个参数又指回了同一个 location,内部跳转绕不出来;location / 和 location ~ \.php$ 都能匹配,兜底文件落进了被 rewrite 的那一段;root 指错了目录,兜底文件不存在所以一直重试。

上来先把内部跳转的循环链打出来

nginx -T | grep -nE 'try_files|rewrite|root'

兜底改成命名 location,避免再次匹配

printf 'location @php {\n  fastcgi_pass unix:/run/php-fpm/www.sock;\n}\n' > /etc/nginx/conf.d/route.conf

try_files 最后一项指向命名 location

sed -i 's#try_files $uri $uri/ /index.php?$query_string#try_files $uri $uri/ @php#' /etc/nginx/conf.d/site.conf

等前面都确认过,再确认 root 下的入口文件真实存在

ls -l /www/wwwroot/site/index.php && nginx -t && nginx -s reload

怎么算真的好了,看的是同一批现象。详情页返回 200,error.log 里不再出现 internal redirection cycle,访问不存在的路径时返回框架的 404 页面而不是 500。

try_files 的兜底最好用命名 location,写成 URI 会重新走一遍匹配;rewrite 加 last 之后也要确认新的一轮能命中终止规则。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189