Spec-Zone.ru › Apache HTTP Server

Продвинутые приемы работы с mod_rewrite

Этот документ дополняет mod_rewrite справочную документацию. В нем описано несколько продвинутых приемов работы с mod_rewrite.

Обратите внимание: многие из этих примеров не будут работать без изменений в вашей конфигурации сервера, поэтому важно разобраться в них, а не просто копировать и вставлять примеры в конфигурацию.

Шардирование на основе URL между несколькими бэкендами

Описание:

Распространенный способ распределения нагрузки на серверы или объема хранилища называется «шардированием». При использовании этого метода фронтенд-сервер использует URL, чтобы последовательно распределять пользователей или объекты по отдельным бэкенд-серверам.

Решение:

Соответствие между пользователями и целевыми серверами хранится во внешних файлах карт. Они выглядят так:

user1 physical_host_of_user1
user2 physical_host_of_user2
# ... and so on

Поместим это в файл map.users-to-hosts. Нужно сопоставить:

/u/user1/anypath

с

http://physical_host_of_user1/u/user/anypath

Таким образом, путь каждого URL не обязан быть доступен на каждом физическом бэкенд-хосте. Следующий набор правил выполняет это преобразование с помощью файлов карт. Предполагается, что server0 — сервер по умолчанию, который будет использоваться, если для пользователя нет записи в карте:

RewriteEngine on
RewriteMap    users-to-hosts      "txt:/path/to/map.users-to-hosts"
RewriteRule   "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"

Дополнительные сведения о синтаксисе этой директивы см. в документации RewriteMap и в руководстве по RewriteMap.

Генерация содержимого на лету

Описание:

Нужно динамически генерировать содержимое, но после генерации сохранять его в статическом виде. Это правило проверяет, существует ли статический файл, и, если его нет, создает его. При необходимости статические файлы можно периодически удалять (например, с помощью cron), и они будут создаваться по запросу.

Решение:
Это выполняется следующим набором правил:
# This example is valid in per-directory context only
RewriteCond "%{REQUEST_URI}"   "!-U"
RewriteRule "^(.+)\.html$"     "/regenerate_page.cgi"   [PT,L]

Оператор -U определяет, является ли проверяемая строка (в данном случае REQUEST_URI) допустимым URL. Для этого выполняется подзапрос. Если этот подзапрос завершается неудачей — то есть запрошенный ресурс не существует, — правило вызывает программу CGI /regenerate_page.cgi, которая создает запрошенный ресурс и сохраняет его в каталоге документов. Поэтому при следующем запросе можно будет выдать статическую копию.

Таким образом, документы, которые обновляются редко, можно выдавать в статическом виде. Если документы нужно обновить, их можно удалить из каталога документов, и при следующем запросе они будут созданы заново.

Балансировка нагрузки

Описание:

Нужно случайным образом распределять нагрузку между несколькими серверами с помощью mod_rewrite.

Решение:

Для этого воспользуемся RewriteMap и списком серверов.

RewriteEngine on
RewriteMap lb        "rnd:/path/to/serverlist.txt"
RewriteRule "^/(.*)" "http://${lb:servers}/$1"     [P,L]

В serverlist.txt будет содержаться список серверов:

## serverlist.txt

servers one.example.com|two.example.com|three.example.com

Если вы хотите, чтобы на один из серверов приходилась большая доля нагрузки, добавьте его в список несколько раз.

Обсуждение

В Apache есть модуль балансировки нагрузки — mod_proxy_balancer, — который гораздо гибче и функциональнее всего, что можно создать с помощью mod_rewrite.

Структурированные каталоги пользователей

Описание:

На некоторых сайтах с тысячами пользователей используется структурированная организация домашних каталогов: т. е. каждый домашний каталог находится в подкаталоге, имя которого начинается (например) с первой буквы имени пользователя. Так, /~larry/anypath — это /home/l/larry/public_html/anypath, а /~waldo/anypath — это /home/w/waldo/public_html/anypath.

Решение:

Используем следующий набор правил, чтобы преобразовать URL с тильдой в описанную выше структуру.

RewriteEngine on
RewriteRule   "^/~(([a-z])[a-z0-9]+)(.*)"  "/home/$2/$1/public_html$3"

Перенаправление на якоря

Описание:

По умолчанию перенаправление на HTML-якорь не работает, поскольку mod_rewrite экранирует символ #, заменяя его на %23. Это, в свою очередь, нарушает работу перенаправления.

Решение:

Используйте флаг [NE] в директиве RewriteRule. NE означает No Escape (не экранировать).

Обсуждение:
Этот прием работает и с другими специальными символами, которые mod_rewrite по умолчанию кодирует в URL.

Переписывание URL в зависимости от времени

Описание:

Нужно с помощью mod_rewrite выдавать разное содержимое в зависимости от времени суток.

Решение:

Для условий переписывания доступно множество переменных с именами TIME_xxx. В сочетании со специальными шаблонами лексикографического сравнения <STRING, >STRING и =STRING можно выполнять перенаправления в зависимости от времени:

RewriteEngine on
RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" ">0700"
RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" "<1900"
RewriteRule   "^foo\.html$"             "foo.day.html" [L]
RewriteRule   "^foo\.html$"             "foo.night.html"

Это позволяет выдавать содержимое foo.day.html по URL foo.html с 07:01-18:59, а в остальное время — содержимое foo.night.html.

mod_cache, промежуточные прокси и браузеры могут кэшировать ответы, из-за чего любая из страниц может отображаться вне заданного временного интервала. Для управления этим эффектом можно использовать mod_expires. Разумеется, гораздо лучше просто выдавать содержимое динамически и изменять его в зависимости от времени суток.

Установка переменных окружения на основе частей URL

Описание:

Иногда при выполнении переписывания URL нужно сохранять некое состояние. Например, может потребоваться отметить, что переписывание уже выполнено, чтобы впоследствии проверить, поступил ли запрос в результате этого переписывания. Один из способов сделать это — установить переменную окружения.

Решение:

Используйте флаг [E], чтобы установить переменную окружения.

RewriteEngine on
RewriteRule   "^/horse/(.*)"   "/pony/$1" [E=rewritten:1]

Позже в наборе правил можно проверить эту переменную окружения с помощью RewriteCond:

RewriteCond "%{ENV:rewritten}" "=1"

Обратите внимание, что переменные окружения не сохраняются при внешнем перенаправлении. Можно использовать флаг [CO], чтобы установить cookie. При переписывании в контексте каталога и в файлах htaccess, когда окончательная подстановка обрабатывается как внутреннее перенаправление, к переменным окружения из предыдущего этапа переписывания добавляется префикс "REDIRECT_".

© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/rewrite/advanced.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API