влияние на производительность порядка правил перезаписи при использовании apache mod_rewrite - PullRequest
6 голосов
/ 25 июня 2011

хотя я читал о «иногда неочевидном способе», которым mod_rewrite обрабатывает различные правила перезаписи, которые вы передаете ему (например: сначала читаете RewriteRule, затем возвращаетесь к проверке RewriteCond), но:

Что касается производительности, имеет ли значение порядок правил?

apache обрабатывает их "сверху вниз"? это означает, что наиболее часто используемые правила технически должны быть как можно ближе к началу списка?

это не вопрос, касающийся перекрывающихся правил и т. Д., Поскольку этот вопрос предполагает, что все правила являются [L] и не перекрываются.

так

Должны ли наиболее часто используемые правила быть как можно ближе к вершине, а менее используемые - к нижней части?

спасибо!

Ответы [ 2 ]

8 голосов
/ 26 июня 2011

В то время как все, что сказал @Corey Henderson, имеет абсолютный смысл ... это не на 100% соответствует реальности.

В вашем .htaccess есть только эти 2 правила (я знаю, это немного глупый пример, но в конечном итоге вы можете столкнуться с тем же эффектом при выполнении сложных переписываний):

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

Можно подумать - перенаправить ВСЕ запросы на index.php.Флаг [L] установлен, поэтому не о чем беспокоиться.Что ж, по-видимому, есть о чем беспокоиться, так как после просмотра флага [L] mod_rewrite переходит на следующую итерацию (вход в цикл).Поскольку у нас есть правило, которое будет всегда выполняться, у нас будет бесконечный цикл (ну, в конфиге Apache есть настройка, которая управляет им - по умолчанию это максимум 10 итераций).Если предел превышен, вы увидите сообщение об ошибке 500 Server и эту строку в файле Apache error.log: "Запрос превысил предел 10 внутренних перенаправлений из-за возможной ошибки конфигурации. Используйте LimitInternalRecursion, чтобы увеличить предел при необходимости.Используйте 'LogLevel debug', чтобы получить обратную трассировку. "

Перезапись прекратится, если:

  1. Больше нет правил для обработки
  2. Внешнее перенаправление [R=301]
  3. Дана явная команда «ничего не переписывать» (второй параметр RewriteRule - назначение должно быть -.
  4. При перезаписи на точно такой же URL, как и в начале итерации.
  5. Уже упоминалось "Запрос превысил предел внутренних перенаправлений xx".

Так что да ... чем быстрее будет перезаписана итерация перезаписи (правило сверху), тем лучшеis.

При заказе ваших правил (когда у вас их довольно много, а не только 1-2-3), вы можете рассмотреть эту логику (какие правила идут сверху):

  1. Правилоs для файлов / папок, которые вы не хотите трогать ВСЕ, ни при каких обстоятельствах (обрабатывать запрос как есть, независимо от домена / протокола)
  2. Правила, которые изменяют домен (например, перенаправление на www.)или протокол (форсирование HTTPS) - чем быстрее вы сделаете это, тем лучше (например, если вы сделаете это слишком поздно, он может уже изменить URL-адрес с «хорошего» на реальный).
  3. Другие важные правила, которые могут повлиятьсуществующие файлы / папки
  4. (подумайте об этом) «нечего переписать» для существующих файлов / папок (см. ниже, вид № 1, но для всех существующих ресурсов)
  5. другие правила
  6. Поймать все правило.

На подавляющем большинстве сайтов, где переписывают URL, у вас не будет более 5-6 правил (файлы .htaccess по умолчанию для большинства PHP-фреймворков, которые я видел +)некоторые продукты, такие как WordPress, просто «ловят все» (если файл / папка не существует, то переписать запрос в index.php)).

У каждого веб-сайта будет своя логика, которая составляет приведенный выше список jПросто общая рекомендация, не более того.


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

Моя главная мысль здесь: Если у вас довольно много правил, подумайте над тем, чтобы вставить такой тип «ничего не переписывать»где-то там, чтобы полностью остановить итерацию.

5 голосов
/ 26 июня 2011

Из документации для RewriteRule:

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

Порядок, в котором определяются эти правила, важен - это порядок, в котором они будут применяться при выполнении-time.

Так что, если вы поместите ваши общие правила перезаписи вверху и по возможности пометите их флагом L , остальные правила не будут обрабатыватьсяи у вас будет оптимизированная конфигурация:

last | L - немедленно прекратить процесс переписывания и больше не применять правила

...