LimitInternalRecursion不能防止重写死循环,仅在内部重定向或子请求嵌套达默认10层时强制中止并报错;它限制两个维度:重写跳转次数和子请求深度,属事后熔断而非逻辑防护。

LimitInternalRecursion 不能防止无限循环,它只在循环已发生且嵌套达阈值时强制中止并报错。这不是预防措施,而是熔断机制——就像电路跳闸,故障已经发生了。
它实际控制什么
该指令限制两个独立维度的嵌套深度:
- 内部重定向链长度(即 mod_rewrite 触发的重写跳转次数)
- 子请求嵌套深度(如 mod_dir 查找 DirectoryIndex、mod_negotiation 处理内容协商时产生的递归)
默认值是 10,表示任一维度达到 10 层就会终止请求,并记录类似 [alert] mod_rewrite: maximum number of internal redirects reached 的错误。只写一个数字(如 LimitInternalRecursion 20)会同时设为两者。
它不能在 .htaccess 中使用,仅支持 server config、virtual host 或 directory 级别配置。
为什么调高它不是解决办法
把值设成 20 或 50,只是让死循环多跑几轮才报错,反而掩盖问题、延长响应时间、增加服务器负担。错误日志里出现该提示,说明规则逻辑本身已有闭环,必须修复规则,而非放宽限制。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
常见误用场景包括:
- 重写目标路径未排除自身(例如重写所有请求到
/index.php,但没加条件跳过对/index.php的再次匹配) - 多条规则之间无
[L]终止,导致后续规则持续介入 - 正则范围重叠(如
^(.*)$和^api/(.*)$共存,后者被前者先捕获再重写,又触发新匹配) - 条件判断恒真(比如用
%{HTTP_HOST}判断却未覆盖当前访问域名)
真正有效的配置习惯
预防靠结构,不靠参数。关键做法有:
- 对所有重写终点路径显式排除:在重写到
/index.php前加上RewriteCond %{REQUEST_URI} !^/index\.php$ - 优先用前缀精确匹配,少用贪婪捕获;例如用
RewriteRule ^/static/ - [L]拦截静态资源,避免落入泛匹配规则 - 每条重写规则末尾尽量加
[L],尤其在.htaccess中——没有它,Apache 会继续遍历后续规则 - 启用调试日志定位源头:
LogLevel alert rewrite:trace3(Apache 2.4+),可清晰看到每次重写触发路径
什么时候可以临时调整这个值
仅限排查阶段:当你怀疑某组规则确实需要较深嵌套(如多层代理 + 内容协商 + 重写),且已确认无逻辑闭环时,可临时设为 15 或 20 并配合 trace 日志观察完整链路。一旦验证完毕,务必还原为默认 10,并确保规则自身具备自终止能力。
不复杂但容易忽略——防循环的关键不在拦得多高,而在起点就避开回环。










