【问题标题】:performance impact of order of rewrite rules when using apache mod_rewrite使用 apache mod_rewrite 时重写规则顺序对性能的影响
【发布时间】:2011-06-25 14:24:19
【问题描述】:

虽然我已经阅读了 mod_rewrite 处理您提供给它的各种重写规则的“有时不明显的方式”(例如:首先读取 RewriteRule,然后返回检查 RewriteCond),但是:

就性能而言,规则的顺序重要吗?

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

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

所以,

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

谢谢!

【问题讨论】:

    标签: performance apache mod-rewrite


    【解决方案1】:

    虽然@Corey Henderson 所说的一切都非常有道理.. 它并不是 100% 符合现实。

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

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

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

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

    1. 无需处理更多规则
    2. 外部重定向[R=301]
    3. 给出了明确的“无需重写”命令(RewriteRule 的第二个参数——目标应为-
    4. 重写到与迭代开始时完全相同的 URL 时。
    5. 已经提到“请求超出了 xx 个内部重定向的限制”。

    所以是的.. 越快的重写迭代将被中断(规则在顶部)越好。

    在排序规则时(当您有很多规则时,而不仅仅是 1-2-3),您可能会考虑以下逻辑(哪些规则在最上面):

    1. 在任何情况下您都不想接触的文件/文件夹的规则(按原样处理请求,无论域/协议如何)
    2. 改变域(例如重定向到www.)或协议(强制HTTPS)的规则——你越快越好(好像你做得太晚了,它可能已经将URL从“nice " 真实)。
    3. 其他可能影响现有文件/文件夹的重要规则
    4. (考虑这样做)现有文件/文件夹“无需重写”(见下文,#1,但所有现有资源)
    5. 其他规则
    6. 抓住所有规则。

    在重写 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]
    

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

    【讨论】:

    • 谢谢!一直在想这个问题。
    【解决方案2】:

    来自 RewriteRule 的文档:

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

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

    因此,如果您将常用的重写规则放在顶部,并尽可能用 L 标志标记它们,它将不会处理其余规则,并且您将获得优化的配置:

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

    【讨论】:

    • 谢谢。下面的答案更详细一点,但这个首先回答了这个问题:)
    猜你喜欢
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 2023-03-18
    • 2011-09-02
    • 2011-03-12
    • 2017-05-25
    • 1970-01-01
    • 2012-07-22
    相关资源
    最近更新 更多