使用apache mod_rewrite时重写规则顺序对性能的影响

时间:2011-06-25 14:24:19

标签: performance apache mod-rewrite

虽然我已经读过mod_rewrite处理你提供的各种重写规则的'有时候不明显的方法'(例如:先读RewriteRule,然后再回去查看RewriteCond),但是:

就表现而言,规则的顺序是否重要?

apache会以“自上而下”的方式处理它们吗?这意味着最常用的规则在技术上应该尽可能接近列表顶部?

这不是关于重叠规则等的问题,因为这个问题假设所有规则都是[L]且不重叠。

所以,

最常用的规则是否应该尽可能接近顶部,而底部附近使用较少的规则?

谢谢!

2 个答案:

答案 0 :(得分:8)

尽管@Corey Henderson所说的所有内容都具有绝对完美的意义......但它并非100%与现实相符。

在你的.htaccess中只有这两个规则(我知道,这是一个有点愚蠢的例子,但你在复杂的重写时可能会遇到同样的效果):

RewriteEngine On
RewriteRule (.*) /index.php?u=$1 [L]

您会认为 - 将所有请求重定向到index.php。标记[L]已设置,因此无需担心。好吧 - 显然需要担心的是,因为看到[L]标志后mod_rewrite进入下一次迭代(进入循环)。因为我们有总是执行的规则,所以我们将有无限循环(好吧,Apache配置中有设置来控制它 - 默认情况下它最多10次迭代)。如果超出限制,那么您将在Apache的error.log中看到500 Server Error消息和此行:“由于可能的配置错误,请求超出了10个内部重定向的限制。如有必要,请使用'LimitInternalRecursion'来增加限制。使用“LogLevel debug”获取回溯。“

如果出现以下情况,重写将停止:

  1. 没有更多要处理的规则
  2. 外部重定向[R=301]
  3. 明确提出“无需重写”命令(RewriteRule的第二个参数 - 目的地应为-
  4. 重写与迭代开始时完全相同的URL。
  5. 已经提到“请求超出了xx内部重定向的限制”。
  6. 所以是的..更快的重写迭代将被中断(规则在顶部)越好。

    在订购规则时(当你有相当多的规则,而不仅仅是1-2-3)时,你可以考虑这个逻辑(哪些规则排在最前面):

    1. 您在任何情况下都不想触及的文件/文件夹的规则(按原样处理请求,不论域/协议)
    2. 更改域名(例如,重定向到www.)或协议(强制使用HTTPS)的规则 - 您执行此操作的速度越快(就好像您执行得太晚,可能已经更改了网址) “很好”真实的。)
    3. 可能影响现有文件/文件夹的其他重要规则
    4. (考虑一下这个)“现在的文件/文件夹没有任何重写”(见下文,#1类似但是对于所有现有资源)
    5. 其他规则
    6. 抓住所有规则。
    7. 在绝大多数重写URL的网站上你都没有更多的5-6规则(我见过的大多数PHP框架的默认.htaccess文件+像WordPress这样的产品只有“全部捕获”(如果是文件) /文件夹不存在然后重写请求index.php))。

      每个网站都有自己的逻辑,这使得上面的列表只是一般性建议,仅此而已。


      # Do not do anything for already existing files
      RewriteCond %{REQUEST_FILENAME} -f [OR]
      RewriteCond %{REQUEST_FILENAME} -d
      RewriteRule .+ - [L]
      

      我的主要观点是:如果您有相当多的规则,请考虑在那里插入这种“无需重写”以完全停止迭代。

答案 1 :(得分:5)

来自RewriteRule的文档:

http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

定义这些规则的顺序非常重要 - 这是它们在运行时应用的顺序。

因此,如果您将常用的重写规则置于顶部,并且只要有可能使用 L 标记标记它们,它就不会处理其余的规则,并且您将进行优化配置:

last | L - 立即停止重写过程,不再应用任何规则