Персональный | |
Модуль mod_accel
17.02.2005 Версия 1.0.34 Модуль mod_accel предназначен для использования Apache в режиме акселератора, то есть, он реализует функциональность ProxyPass модуля mod_proxy. Однако, в отличие от mod_proxy, mod_accel правильно взаимодействует с бэкендом (подробнее об этом ниже), может учитывать при кэшировании cookie, использовать busy lock'и и ограничивать число соединений с бэкендом, позволяет записывать в лог результаты своей работы и, наконец, ответы mod_accel могут быть перекодированы Russian Apache'ем и сжаты модулем mod_deflate. Модуль mod_accel не может работать в режиме обычного прокси-сервера как mod_proxy. Однако вряд ли целесообразно использовать Apache в этом качестве вместо Squid и Oops. Тем не менее, часто при конфигурировании mod_proxy вместе с функциональностью акселератора по ошибке разрешают стандартное проксирование (ProxyRequests on), что приводит к появлению очередного публичного прокси-сервера. И в то же время, использование Squid или Oops в качестве акселератора менее удобно, чем Apache, поскольку Apache может также обрабатывать обычные непроксируемые запросы. mod_accel представляет из себя собственно модуль, использующий Apache EAPI, и набор патчей для Apache и модулей mod_proxy, mod_rewrite, mod_ssl и mod_charset (Russian Apache). Кроме того, в дистрибутиве есть три модуля - mod_randban, mod_quoted и mod_freeze, модифицирующие тело передаваемого ответа. Первый изменяет случайное значение в URL'ах для вызова баннеров, второй перекодирует русские символы в конструкциях вида '<a href="/show?%80%81%82">', а третий изменяет некоторые активные теги и параметры. СодержаниеУстановкаДинамическая загрузка Как это работает Когда ответ может быть получен из кэша Busy lock'и Ограничение числа запросов Примитивное распределение нагрузки и отказоустойчивость Какие ответы кэшируются Заметки, с помощью которых можно управлять модулем Как работать с cookie Что можно записать в лог Чистка кэша Директивы
Менеджер кэша Модуль mod_randbanМодуль mod_quotedМодуль mod_freezeВзаимодействие с модулем mod_rewrite Настройка производительности Как mod_proxy взаимодействует с бэкендом Установка
Дистрибутив необходимо распаковать, перейти в каталог с исходными текстами
и выполнить команду Исходные тексты EAPI можно взять из дистрибутива mod_ssl, сам модуль mod_ssl при этом устанавливать не нужно, например:tar zxf mod_accel-1.0.34.tar.gz cd mod_accel-1.0.34 ./configure --with-apache=<apache_dir> --with-eapi=<eapi_dir> make Если же Apache будет собираться с использованием модуля mod_ssl, то параметр./configure --with-apache=../apache_1.3.20 --with-eapi=../mode_ssl-2.8.4-1.3.20/pkg.eapi --with-eapi не нужен,
поскольку mod_ssl сам устанавливает Apache EAPI.
Нужно заметить, что версии EAPI, идущие в составе mod_ssl-2.8.13-1.3.27 и mod_ssl-2.8.14-1.3.27 не правильно работают с разделяемой памятью, необходимой при использовании busy lock'ов и ограничении числа соединений и ждущих процессов. Поэтому, начиная с версии 1.0.28, mod_accel при конфигурировании проверяет наличие EAPI с ошибками и патчит его при необходимости. При использовании модулей mod_charset или mod_ssl их необходимо установить до mod_accel, поскольку при установке mod_accel эти модули необходимо патчить. mod_ssl рекомендуется устанавливать так, как описано в разделе "The flexible APACI-only way [FOR REAL HACKERS]" файла INSTALL из дистрибутива mod_ssl. При конфигурировании можно указать ещё несколько параметров:
Начиная с версии 1.0.7, параметры
Команда Если предполагается использовать busy lock'и и ограничение числа соединений и ждущих процессов, то нужно также установить библиотеку mm (она доступна по адресу http://www.engelschall.com/sw/mm/): С параметромtar zxf mm-1.2.1.tar.gz cd mm-1.2.1 ./configure --disable-shared make --disable-shared библиотека будет
собрана статически.
Библиотеку можно собрать динамически, но в этом случае после сборки
её нужно установить командой make install .
При конфигурировании Apache необходимо активировать модули, EAPI и EAPI_MM (если используется библиотека mm): До версии mod_accel 1.0.7 модуль mod_accel должен быть указан после модулей mod_quoted и mod_randban. Начиная с версии 1.0.7, порядок не имеет значения. В случае, если библиотека mm собрана динамически, переменнаяcd <apache_dir> EAPI_MM=<mm_dir> ./configure ... --enable-rule=EAPI --activate-module=src/modules/extra/mod_randban.o --activate-module=src/modules/extra/mod_quoted.o --activate-module=src/modules/extra/mod_freeze.o --activate-module=src/modules/accel/libaccel.a ... EAPI_MM будет выглядеть таким образом:
EAPI_MM=SYSTEM После установки Apache необходимо сделать каталог, в котором будут создаваться файлы кэша и временные файлы. Пользователь, от имени которого работают процессы Apache, должны иметь права на чтение и запись в этот каталог. Этот каталог нужно указать в директиве AccelCacheRoot, например: AccelCacheRoot cache Динамическая загрузкаМодуль mod_accel может подгружаться динамически. Начиная с версии 1.0.7, порядок загрузки не имеет значения. До версии 1.0.7, как и при статической сборке, модуль mod_accel должен быть указан после модулей mod_quoted и mod_randban: Если модуль mod_ssl тоже загружается динамически, то он должен быть указан до модуля mod_accel (это также не имеет значения, начиная с версии 1.0.7):LoadModule randban_module modules/mod_randban.so LoadModule quoted_module modules/mod_quoted.so LoadModule accel_module modules/libaccel.so LoadModule ssl_module modules/libssl.so LoadModule accel_module modules/libaccel.so Как это работаетВ фазе трансляции URI mod_accel проверяет, не совпадает ли начало URI c каким-либо из префиксом, указанных в списке директив AccelPass. Если совпадение найдено, то просматривается список директив AccelNoPass. Если в этом списке не найден ни один префикс или регулярное выражение, соответствующие URI, то обработчиком этого запроса будет "accel-handler", который направит этот запрос на другой сервер. Например, запрос "http://frontend/test/one.cgi?test=1" директива преобразует в запрос "http://backend/test/one.cgi?test=1".AccelPass /test/ http://backend/test/ Если ответ на запрос может быть закэширован, то проверяется его наличие в кэше. Ключом для поиска в кэше является результат хэш-функции md5, в качестве аргумента которой передаётся преобразованный URL, в нашем случае "http://backend/test/one.cgi?test=1". Если ответ найден в кэше, то он считывается блоками, размер которых задаётся директивой AccelCacheSendSize и отдаётся клиенту. Если же ответа нет, или он устарел, или же ответ вообще некэшируемый, то запрос должен быть передан бэкенду. После этого проверяются busy lock'и, число соединений с бэкендом и число ждущих процессов. Затем, если у запроса есть тело (например, запрос вида POST), то оно считывается в буфер, размер которого задаётся директивой AccelRequestBuffSize. Если тело запроса превышает размер буфера, то оно сохраняется во временный файл. И только после этого mod_accel соединяется с бэкендом (или с одним из них), передаёт ему запрос и затем читает заголовок ответа. Сокеты бэкенда и клиента переводятся в неблокирующий режим и клиенту передаётся заголовок ответа. После этого читается тело ответа в буфер приёма ответа, размер которого задаётся директивой AccelBkRcvBuffSize. Как только размер считанного становится равным размеру этого буфера, создаётся временный файл и в него записывается содержимое буфера. По мере получения ответа он отдаётся клиенту блоками размером, заданным директивой AccelSendSize. В процессе передачи ответа клиенту он может модифицироваться цепочкой модулей, например, модулями mod_randban, mod_quoted и mod_freeze. Как только ответ от бэкенда получен полностью, сокет бэкенда закрывается, а сокет клиента переводится в блокирующий режим. После этого ответ может быть записан в кэш и может использоваться другими процессами Apache. Когда ответ может быть получен из кэшаПрежде чем запрос будет передан бэкенду, проверяется наличие ответа в кэше. Это происходит в следующем порядке:
Если предыдущие проверки пройдены, то считается, что ответ на запрос в принципе может быть закэширован.
Если ответ на запрос есть в кэше, но уже устарел, то в запрос
к бэкенду добавляется заголовок
Если ответ на запрос клиента может быть не полным, например,
если в запросе клиента есть заголовки То же самое относится к запросу HEAD. Если ответа в кэше нет, но он в принципе кэшируемый, то к бэкенду делается запрос GET, чтобы опять же получить полный ответ и, возможно, сохранить его в кэше. Клиенту же возвращается только заголовок ответа. Busy lock'иПрежде чем запрос уходит к бэкенду, предварительно проверяются busy lock'и, число соединений с бэкендом и число ждущих процессов. Busy lock позволяет не передавать бэкенду кэшируемый запрос в том случае, если точно такой же запрос уже обрабатывается бэкендом. Busy lock устанавливается директивой AccelBusyLock и гарантирует, что в течение заданного времени от начала выполнения запроса к бэкенду только один из процессов Apache передаст этот запрос бэкенду. Если в кэше есть устаревший ответ на этот запрос, но он устарел не более чем на время, заданное директивой AccelMaxStale, то все остальные процессы будут возвращать этот устаревший ответ из кэша. В противном случае все остальные процессы, выполняющие такой же запрос, будут или ждать ответ, который получит первый процесс, или же ждать истечения busy lock'а, установленного этим процессом. AccelBusyLock позволяет установить три значения busy lock'а. Первый используется в случае, если ответа в кэше нет или он устарел более чем на время, заданное директивой AccelMaxStale. Второй используется в случае, если ответ в кэше устарел менее чем на время, заданное предыдущей директивой. Второе значение рекомендуется устанавливать больше, чем первое. Третий задаёт максимальное время, которое процесс может провести в busy lock'е, поскольку процесс может ждать последовательно освобождения нескольких busy lock'ов. Предположим, что пришли одновременно три одинаковых запроса и у на заданы такие параметры: Первый запрос будет передан бэкенду. Два других ждут в busy lock'е. Предположим, что по истечении 20 секунд ответ от бэкенда не получен. Второй запрос передаётся бэкенду, третий же продолжает ждать первые два ответа. Но максимальное суммарное время его ожидания не может быть более 30 секунд, поэтому если в течение этого времени бэкенд не ответит, то третий запрос будет передан бэкенду при условии, что число соединений с бэкендом не достигло максимума.AccelBusyLock 20 25 30 Допустим, у нас заданы такие параметры: Проиллюстрируем логику работы busy lock'ов следующим примером:AccelBusyLock 10 15 AccelMaxStale 60
Ограничение числа запросов
Busy lock'и предназначены для уменьшения нагрузки на бэкенд.
В то же время возможны ситуации, когда бэкенд не справляется
со обработкой полученных запросов, а новые запросы продолжают поступать.
В этом случае процессы фронтенда, обрабатывающие новые запросы,
будут или ждать ответа от бэкенда, подсоединившись к нему,
или пытаться соединиться с бэкендом, или же ждать в busy lock'е.
Число процессов фронтенда при этом может достигнуть своего максимума
и если фронтенд кроме проксирования этого бэкенда должен заниматься
ещё и другими запросами, то эти запросы не будут обслуживаться.
Таким образом, один перегруженный бэкенд может сделать недоступными
остальные ресурсы, обслуживаемые его фронтендом.
Для избежания подобных ситуаций в директиве
AccelPass можно указать флаги
MC и MW, позволяющие ограничить
соответственно число соединений с бэкендом и число процессов,
ждущих этот бэкенд в busy lock'е.
Если достигнут максимум по одному из параметров и в кэше есть ответ на запрос,
то он всегда возвращается клиенту, независимо от того, насколько он устарел.
Если же ответа в кэше нет, то возвращается ошибка
Примитивное распределение нагрузки и отказоустойчивость
Примитивное распределение нагрузки и отказоустойчивость можно
реализовать на основе DNS, когда одно имя соответствует нескольким IP-адресам.
Необходимо заметить, что указание альтернативных адресов
в файле Примитивную отказоустойчивость можно реализовать, задав небольшое значение второму параметру директивы AccelTimeout. По умолчанию таймаут на соединение равен примерно 75 секундам. При нормальной работе соединение, как правило, устанавливается за доли секунды. Если установить этот таймаут на несколько секунд, то по его истечении mod_accel попытается подсоединиться к следующему бэкенду. Однако не всегда бэкенд может вернуть результат, даже если фронтенд смог с ним соединиться. Поэтому по истечении таймаутов, заданных параметрами директивы AccelTimeout, при обрыве соединения с бэкендом или при получении ответа с результатом 5XX mod_accel закрывает соединение и переходит к следующему бэкенду. С помощью директивы AccelRetry5XX off можно запретить пытаться соединиться с другим бэкендом при получении ответа с результатом 5XX. Результаты попыток соединений фиксируются в заметках, то есть, их можно увидеть в логе, но они никак не используются для выбора бэкенда при следующих запросах. Какие ответы кэшируютсяРешение от том, кэшировать полученный ответ или нет, принимается в следующем порядке:
Заметки, с помощью которых можно управлять модулемНачиная с версии 1.0.2, поведением модуля mod_accel можно управлять с помощью заметки "accel_nocache". Если выставить эту заметку, то mod_accel всегда будет делать запрос к бэкенду, не проверяя кэш. Полученный ответ никогда не кэшируется, а если в кэше ответ уже есть, то он не удаляется. Начиная с версии 1.0.24, то же самое можно делать с помощью переменной среды "ACCEL_NOCACHE". Начиная с версии 1.0.18, модулю mod_accel в заметке "accel_request_body" можно передавать тело запроса. Начиная с версии 1.0.18, модулю mod_accel в заметке "accel_rewrite_response" можно передавать адрес процедуры для обработки ответа бэкенда. Процедура должна иметь следующий прототип: Она вызывается после получения заголовка и, возможно, первой части ответа от бэкенда. Если ответ бэкенда нужно вернуть неизменным, то процедура должна вернуть значение DECLINED и mod_accel продолжит обработку запроса. При возврате любого другого значения предполагается, что процедура сама полностью обработала запрос.int rewrite_handler(accel_rec *a); Как работать с cookieЕсли ответы могут быть закэшированы, то заголовок "Cookie" удаляется из запроса к бэкенду, а заголовок "Set-Cookie" - из ответа бэкенда, поскольку cookie может влиять на содержимое ответа. Однако, если Вы уверены, что cookie никак не влияют на содержимое ответов, то можете установить директиву AccelPassCookie on. Если Вы уверены, что заголовок "Set-Cookie" имеет смысл кэшировать, то можете установить директиву AccelCacheSetCookie on. Кроме того, можно кэшировать ответ в зависимости от cookie с помощью директивы AccelCacheCookie. Наконец, если авторизация сделана с помощью cookie, то можно использовать директиву AccelRevalidateUser. Что можно записать в логДеятельность mod_accel можно анализировать с помощью заметок, которые можно записывать в лог в виде %{accel}x:
Чистка кэша
Чистка кэша делается отдельным процессом - сборщиком мусора,
который запускается основным сервером Apache и им же контролируется.
После старта сборщик мусора переключается на пользователя и группу,
указанных в директивах User и Group.
Большую часть времени этот процесс спит, просыпаясь лишь для чистки кэша.
Его можно отличить от других процессов Apache с помощью команды
Сборщик удаляет файлы в кэше, которые устарели более часа назад или же к ним не обращались в течение времени, заданного директивой AccelCleanLastAccessed и не следит за размером кэша, поскольку это имеет смысл в случае проксирования Интернета, а не конкретного сайта, размер которого более или менее известен. Кроме того, сборщик удаляет временные файлы, к которым не обращались более часа и каталоги и файлы кэша, оставшиеся после изменения структуры кэша. ДирективыДиректива AccelAddViasyntax: AccelAddVia on|offdefault: AccelAddVia off context: server config, virtual host, location, files
Директива определяет, добавлять или нет в заголовок "Via" в запросе,
передаваемом бэкенду, строку о фронтенде.
Добавляемая строка имеет следующий вид -
Директива AccelAddXForwardedForsyntax: AccelAddXForwardedFor on|offdefault: AccelAddXForwardedFor off context: server config, virtual host, location, files Директива определяет, добавлять или нет в заголовок "X-Forwarded-For" в запросе, передаваемом бэкенду, IP-адрес, с которого был сделан запрос к фронтенду. Директива AccelBkRcvBuffSizesyntax: AccelBkRcvBuffSize размерdefault: AccelBkRcvBuffSize 16 context: server config, virtual host, location, files Директива задаёт размер буфера в килобайтах для приёма ответа от бэкенда. Если размер ответа превышает размер буфера, то содержимое буфера записывается во временный файл. Директива AccelBkRcvSockBuffSizesyntax: AccelBkRcvSockBuffSize размерdefault: AccelBkRcvSockBuffSize 0 context: server config, virtual host, location, files Директива задаёт размер TCP-буфера ядра в килобайтах для приёма ответа от бэкенда. Размер устанавливается системным вызовом setsockopt() с параметром SO_RCVBUF. Если значение директивы равно нулю, то setsockopt() не вызывается и используется размер TCP-буфера, заданный по умолчанию. Директива AccelBusyLocksyntax: AccelBusyLock "время" ["время" ["время"]]default: AccelBusyLock 0 0 AccelTimeout context: server config, virtual host, location, files
Директива задаёт три значения busy lock'ов.
Первый используется в случае, если ответа в кэше нет или он
устарел более чем на время, заданное директивой
AccelMaxStale.
Второй используется в случае, если ответ в кэше устарел
менее чем на время, заданное предыдущей директивой.
Третий задаёт максимальное время ожидания в busy lock'е.
Подробно логика работы busy lock'ов описана в разделе
"Busy lock'и".
Оба параметра можно задавать в виде строки, например,
Если второй параметр не задан, то он равен первому. Если третий параметр не задан, то он равен первому параметру директивы AccelTimeout. Третий параметр появился в mod_accel, начиная с версии 1.0.7. В более ранних версиях его значение равно первому параметру директивы AccelTimeout. Директива AccelCacheCookiesyntax: AccelCacheCookie off|all|[!]строка|[!]~[*]регулярное выражениеdefault: AccelCacheCookie off context: server config, virtual host, location, files compatibility: mod_accel 1.0.2 и выше Директива задаёт имена cookie, которое будет учитываться при кэшировании ответа сервера. При задании имени cookie можно использовать имя или регулярное выражение. Символы "~*" позволяют задать регулярное выражение без учёта регистра символов. Параметр "all" задаёт все cookie. Символ "!" позволяет исключить часть cookie. Параметр "off" запрещает учёт cookie при кэшировании. Предположим, у нас заданы директивы В этом случае запрос "http://frontend/test/one.html" будет перенаправлен в запрос "http://backend/test/one.html". Ключом для поиска в кэше является результат хэш-функции md5, в качестве аргумента которой передаётся преобразованный URL, в нашем случае "http://backend/test/one.cgi?test=1". Однако, если пользователь передал cookie, например, "userid=12345; pref=34; id=92", то аргументом хэш-функции md5 будет строкаAccelPass /test/ http://backend/test/ AccelCacheCookie all !~^id Директива учитывает только заголовки "Cookie", приходящие от клиента, и никак не влияет на заголовок "Set-Cookie", переданный от бэкенда. В одном блоке может быть задано несколько директив AccelCacheCookie. Если в блоке не указана ни одна директива, то они наследуются из предыдущего. Директивы, заданные в вложенном блоке не объединяются с директивами, заданными в предыдущем блоке. Параметр "off" отменяет действие всех остальных параметров. В версии 1.0.2 допустимы только два вида параметров - "off" и строка. Кроме того, в одной директиве можно указывать только один параметр и имена cookie не сортируются. Директива AccelCacheRootsyntax: AccelCacheRoot путь [1|2 [1|2 [1|2]]] [noauto]default: AccelCacheRoot нет 1 2 context: server config
Директива задаёт каталог, в котором будут создаваться файлы кэша
и временные файлы. Весь кэш должен находиться на одном
дисковом разделе, так как временные файлы перемещаются в кэш
операцией указывает, что кэш находится в каталогеAccelCacheRoot /var/cache 1 1 noauto /var/cache ,
глубина его вложенности 2, имена каталогов обоих
уровней Директива AccelCacheSendSizesyntax: AccelCacheSendSize размерdefault: AccelCacheSendSize 8 context: server config, virtual host, location, files Директива определяет размер буфера в килобайтах для передачи ответа из кэша клиенту. Директива AccelCacheSetCookiesyntax: AccelCacheSetCookie on|offdefault: AccelCacheSetCookie off context: server config, virtual host, location, files compatibility: mod_accel 1.0.23 и выше Директива определяет, можно ли сохранять в кэш заголовок "Set-Cookie". Директива AccelCleansyntax: AccelClean "[@] время"default: AccelClean "1 hour" context: server config Директива задаёт время или интервал чистки кэша. Если в строке указан символ "@", то чистка делается раз в сутки в указанное время, иначе значение означает интервал времени, по истечении которого производится чистка кэша. Примеры использования: AccelClean "1 hour 30 minutes" AccelClean "@ 5 hours" Директива AccelCleanLastAccessedsyntax: AccelCleanLastAccessed "время"default: AccelCleanLastAccessed "24 hours" context: server config Директива определяет максимальное время неактивной жизни файла в кэше. Если в течение этого времени к файлу не обращались, то файл будет удалён при чистке кэша, даже если он не считается устаревшим. Директива AccelContentTailsyntax: AccelContentTail длинаdefault: AccelContentTail 32 context: server config compatibility: mod_accel 1.0.0-1.0.10 Директива задаёт размер буфера, используемого модулями, модифицирующими тело ответа. Начиная с версии 1.0.11, размер буфера настраивается автоматически и директива упразднена. Директива AccelDefaultExpiresyntax: AccelDefaultExpire "время"default: AccelDefaultExpire 0 context: server config, virtual host, location, files Директива задаёт время хранения ответа при условии, что определить это время другими способами не удалось. Директива AccelIgnoreAuthsyntax: AccelIgnoreAuth on|offdefault: AccelIgnoreAuth off context: server config, virtual host, location, files compatibility: mod_accel 1.0.5 и выше
Директива определяет, игнорировать или нет заголовок "Authorization"
в запросе клиента.
Директиву можно применять в случае, если авторизация проводится
фронтендом и ответ бэкенда не зависит от пользователя и следовательно
может выдаваться из кэша.
Кроме того, некоторые программы пакетного скачивания, в частности FlashGet,
используют заголовок "Authorization" в роли заголовка
Директива AccelIgnoreExpiressyntax: AccelIgnoreExpires on|offdefault: AccelIgnoreExpires off context: server config, virtual host, location, files Директива определяет, игнорировать или нет заголовки "Expires" и "Cache-Control", выдаваемые бэкендом. Директива AccelIgnoreNoCachesyntax: AccelIgnoreNoCache on|offdefault: AccelIgnoreNoCache off context: server config, virtual host, location, files
Директива определяет, игнорировать или нет заголовки
При нажатии на Reload Netscape посылает заголовок
При нажатии на Refresh MSIE под Windows до версии 5.5 включительно
посылает заголовок
При нажатии на Reload Konqueror посылает заголовки
Заголовок Директива AccelInvalidatesyntax: AccelInvalidate строка|offdefault: AccelInvalidate off context: server config, virtual host, location, files Директива задаёт строку, при нахождении которой в конце URL содержимое кэша для данного запроса будет обновлено. Например, если задана директива то для обновления запроса "http://frontend/test/one.hml?arg=1", нужно сделать запрос "http://frontend/test/one.hml?arg=1_INVALIDATE".AccelInvalidate _INVALIDATE Директива AccelLastModifiedFactorsyntax: AccelLastModifiedFactor числоdefault: AccelLastModifiedFactor 0 context: server config, virtual host, location, files Директива задаёт число в процентах для определения времени кэширования на основании текущего времени и заголовка "Last-Modified". Подробно это описано в разделе "Какие ответы кэшируются". Директива AccelMaxStalesyntax: AccelMaxStale "время"default: AccelMaxStale 0 context: server config, virtual host, location, files
Директива задаёт время, в течение которого устаревший ответ на запрос
может отдаваться из кэша при условии, что один из процессов
Apache уже получает обновлённый ответ от бэкенда.
Оба параметра можно задавать в виде строки, например,
Директива AccelModRewriteLocationsyntax: AccelModRewriteLocation on|offdefault: AccelModRewriteLocation off context: server config, virtual host, location, files compatibility: mod_accel 1.0.30 и выше Директива указывает, использовать ли mod_rewrite для переписывания заголовков "Location" и "Refresh". Директива AccelNoCachesyntax: AccelNoCache on|offdefault: AccelNoCache off context: server config, virtual host, location, files Директива указывает, могут ли ответы на запросы кэшироваться. Директива AccelNoPasssyntax: AccelNoPass префикс|~[*]регулярное выражениеdefault: нет context: server config, virtual host Эта директива определяет, какие запросы не должны передаваться на другой сервер, даже если префикс запроса совпадает с одним из префиксов, указанных в директиве AccelPass. Это может быть полезно в случае, когда сайт от корня создаётся бэкендом, но статические файлы лучше отдавать фронтендом. Например, если заданы такие директивы то запросы, начинающиеся на "/images/" или "/download/", не будут передаваться бэкенду. Кроме того, запросы заканчивающиеся на ".jpg" или ".JPG" также не будут передаваться бэкенду. Символы "~*" перед регулярным выражением указывают игнорирование регистра. Необходимо заметить, что регулярные выражения применяются только к URI, и не применяются к PATH_INFO и аргументам запроса.AccelPass / http://backend/ AccelNoPass /images/ /download/ ~*\.jpg$ В одном блоке может быть задано несколько директив. Директивы, заданные в вложенном блоке объединяются с директивами, заданными в предыдущем блоке. В mod_accel до версии 1.0.3 нельзя использовать регулярные выражения с игнорированием регистра. Кроме того, в директиве можно использовать только один параметр и между регулярным выражением и символом "~" может стоять пробел. Директива AccelPasssyntax: AccelPass префикс url [флаги]default: нет context: server config, virtual host Директива определяет, какие запросы должны передаваться на другой сервер. Например, директива будет перенаправлять все запросы, начинающиеся на /test/, в запросы "http://backend/test/". Например, запрос "http://frontend/test/one.html" будет перенаправлен в запрос "http://backend/test/one.html".AccelPass /test/ http://backend/test/ Если не установлен флаг PH, то в запрос всегда включается заголовок "Host", содержащий имя и порт (если порт не равен 80) сервера, на который перенаправлен запрос. Если ответ на запрос представляет из себя редирект, то заголовок "Location" при необходимости корректируется, то есть, если заголовок "Location" содержит "http://backend/test/two.html", то он будет изменён на "http://frontend/test/two.html". В этом смысле директива эквивалента двум директивам модуля mod_proxyAccelPass /test/ http://backend/test/ Кроме заголовка "Location" также корректируется заголовок "Refresh".ProxyPass /test/ http://backend/test/ ProxyPassReverse /test/ http://backend/test/ Начиная с версии 1.0.29, mod_accel также корректирует заголовок "Destination", если имя хоста в этом заголовке совпадает с содержимым заголовка "Host", или же если URI не абсолютный. Начиная с версии 1.0.11, в ответ на запрос /test mod_accel возвращает редирект на URL с добавленным слэшом, то есть, http://frontend/test/. Директивы просматриваются в порядке их описания, поэтому более общие префиксы нужно располагать в конце, например: AccelPass /test/ http://backend1/test/ AccelPass / http://backend2/ В директиве можно использовать следующие флаги:
Начиная с версии 1.0.14, mod_accel сначала проверяет директивы AccelPass из виртуального сервера, а лишь затем директивы из основного сервера. Такой порядок позволяет задать в основном сервере директиву с флагом PH, а затем переопределить её в некоторых виртуальных серверах. Начиная с версии 1.0.16, mod_accel позволяет использовать в директиве AccelPass специальное имя хоста _the_same_host_, например: В этом случае mod_accel в качестве IP-адреса бэкенда будет использовать тот же IP-адрес, что и у фронтенда. Необходимо заметить, что при использовании этого имени хоста автоматически устанавливается флаг PH. Если вместе с именем _the_same_host_ заданы флаги MC или MW, но не задан флаг MP, то для ограничения числа соединений или ждущих процессов используется ip-адрес хоста. При формировании ключа в кэше используется IP-адрес бэкенда.AccelPass / http://_the_same_host_:8080/ Флаг MP вместе с _the_same_host_ работает корректно, начиная с версии 1.0.20. Начиная с версии 1.0.27, бэкенд, доступный через _the_same_host_, может использовать named-based виртуальные хосты. Директива AccelPassCookiesyntax: AccelPassCookie on|offdefault: AccelPassCookie off context: server config, virtual host, location, files Директива определяет, можно ли передавать cookie клиента бэкенду, если его ответ на запрос в принципе может быть закэширован. Поскольку ответы на запросы с одинаковым URL могут отличаться в зависимости от содержимого cookie, то такие ответы кэшировать нельзя. Поэтому, если ответ в принципе может быть закэширован, то в запрос в бэкенду не включаются cookie, переданные клиентом. Однако возможна конфигурация, когда бэкенд сам указывает, какие ответы нужно кэшировать, а какие - нет. В этом случае можно разрешить передачу cookie бэкенду. Директива передаёт заголовки "Cookie", приходящие от клиента, и заголовки "Set-Cookie", переданные от бэкенда, но никак не влияет на их кэширование. Директива AccelPassServersyntax: AccelPassServer on|offdefault: AccelPassServer off context: server config, virtual host, location, files compatibility: mod_accel 1.0.16 и выше Директива определяет, нужно ли сохранять заголовок "Server", установленный бэкендом, или же этот заголовок должен быть установлен фронтендом. Возможность устанавливать собственный заголовок "Server" появилась в Apache 1.3.24, и если с этой версией Apache используется mod_accel более ранний, чем 1.0.16, то клиенту будет передаваться заголовок "Server", установленный бэкендом. По умолчанию эта директива выключена и mod_accel-1.0.16, как и предыдущие версии, не передаёт заголовок бэкенда "Server". При использовании с Apache 1.3.26 и старше и mod_accel версий 1.0.16-1.0.20 заголовок "Server" вообще не выдаётся, если директива выключена. Исправлено в mod_accel-1.0.21. Директива AccelPassXAccelsyntax: AccelPassXAccel on|offdefault: AccelPassXAccel off context: server config, virtual host, location, files compatibility: mod_accel 1.0.22 и выше Директива определяет, нужно ли передавать клиенту заголовок "X-Accel-Expires", установленный бэкендом. Эта директива полезна при использовании каскада из двух mod_accel, тогда на сервере, более близком к бэкенду, нужно разрешить передачу X-Accel-Expires для первого фронтенда. Директива AccelRetry5XXsyntax: AccelRetry5XX on|offdefault: AccelRetry5XX on context: server config, virtual host, location, files compatibility: mod_accel 1.0.18 и выше Директива определяет, нужно ли пытаться соединиться с другим бэкендом, если результат ответа равен 5XX и используется примитивное распределение нагрузки и отказоустойчивость. Директива AccelRequestBuffSizesyntax: AccelRequestBuffSizedefault: AccelRequestBuffSize 8 context: server config, virtual host, location, files Директива определяет размер буфера в килобайтах для приёма тела запроса. Если размер последнего превышает размер буфера, то используется временный файл. Директива AccelRevalidateUsersyntax: AccelRevalidateUser on|offdefault: AccelRevalidateUser off context: server config, virtual host, location, files Директиву можно применять в случае, если выполняются все нижеперечисленные условия:
Если директива активна, то при наличии в кэше ответа на запрос, выполняется запрос к бэкенду с заголовком "If-Modified-Since". Директива AccelReversesyntax: AccelReverse префикс urldefault: нет context: server config, virtual host compatibility: mod_accel 1.0.10 и выше Директива определяет, какие URL в заголовках "Location" и "Refresh" должны корректироваться. Например, если задана директива и заголовок "Location" содержит "http://backend/test/two.html", то он будет изменён на "http://frontend/test/two.html".AccelReverse / http://backend/ Директива AccelReverse аналогична директиве ProxyPassReverse модуля mod_proxy, однако её не нужно использовать совместно с директивой AccelPass, поскольку AccelPass уже имеет функциональность AccelReverse. Область применения директивы AccelReverse использование mod_accel совместно с модулем mod_rewrite. Начиная с версии 1.0.26, AccelReverse может использоваться для коррекции заголовков независимо от того, как делается проксирование с помощью AccelPass или же модулем mod_rewrite. Директива AccelSendSizesyntax: AccelSendSize размерdefault: AccelSendSize 8 context: server config, virtual host, location, files Директива определяет размер буфера в килобайтах для передачи ответа бэкенда клиенту. Директива AccelSetXHostsyntax: AccelSetXHost on|offdefault: AccelSetXHost off context: server config, virtual host, location, files Директива определяет, добавлять или нет заголовок "X-Host" в запрос, передаваемом бэкенду. В этом заголовке передаётся содержимое заголовка "Host", переданное фронтенду клиентом. Директива AccelSetXRealIPsyntax: AccelSetXRealIP on|offdefault: AccelSetXRealIP off context: server config, virtual host, location, files Директива определяет, добавлять или нет заголовок "X-Real-IP" в запрос, передаваемом бэкенду. В этом заголовке передаётся IP-адрес, с которого был сделан запрос к фронтенду. Директива AccelSetXURIsyntax: AccelSetXURI on|offdefault: AccelSetXURI off context: server config, virtual host, location, files compatibility: mod_accel 1.0.18 и выше Директива определяет, добавлять или нет заголовок "X-URI" в запрос, передаваемом бэкенду. В этом заголовке передаётся URI, переданный фронтенду клиентом. Директива работает, только начиная с версии 1.0.28. Директива AccelSetXURLsyntax: AccelSetXURL on|offdefault: AccelSetXURL off context: server config, virtual host, location, files Директива определяет, добавлять или нет заголовок "X-URL" в запрос, передаваемом бэкенду. В этом заголовке передаётся URL, переданный фронтенду клиентом. Директива AccelTimeoutsyntax: AccelTimeout "время" ["время"]default: AccelTimeout Timeout Timeout context: server config, virtual host, location, files
Директива задаёт таймауты при работе с бэкендом.
Первый параметр определяет таймаут при передаче запроса бэкенду и чтении его
ответа. Второй параметр определяет таймаут на соединение с бэкендом.
Оба параметра можно задавать в виде строки, например,
Задавать большой таймаут при работе с бэкендом имеет смысл в том случае, если до истечения таймаута ответ от бэкенда всё же может быть получен и этот ответ кэшируется. Тогда последующие запросы будут отдаваться из кэша до тех пор, пока ответ не устареет. В этом случае рекомендуется устанавливать директивой AccelBusyLock значения busy lock'ов большие, чем значение таймаута. Задавать небольшие значения обоих таймаутов рекомендуется для реализации примитивного распределения нагрузки и отказоустойчивости. Директива AccelUnlinkNoCachedsyntax: AccelUnlinkNoCached on|offdefault: AccelUnlinkNoCached off context: server config, virtual host, location, files Директива определяет, нужно ли удалять из кэша ответы, даже если они не могут быть закэшированы. Директива AccelWaitBeforeBodyReadsyntax: AccelWaitBeforeBodyRead время в миллисекундахdefault: AccelWaitBeforeBodyRead 0 context: server config, virtual host, location, files Директива определяет время ожидания в миллисекундах между первым и вторым чтением ответа бэкенда. Известные ошибки и особенности
Менеджер кэша
При сборке mod_accel так же собирается менеджер кэша при условии,
что mod_accel не был сконфигурирован
с параметром После этого менеджер кэша может быть вызван с двумя параметрами "/cachemgr?action=<action>&url=<url>", причём url должен быть обязательно последним. Параметр action может принимать два значения: refresh для обновления содержимого кэша и remove для удаления файла из кэша. Действие remove не работало в версиях mod_accel 1.0.4-1.0.24. Параметр url должен задаваться без префикса "http://", имени хоста и порта. При ответе cachemgr добавляет три заголовка:<Location /cachemgr> SetHandler "accel-cachemgr" </Location>
Модуль mod_randbanМодуль mod_randban подставляет случайное число в ответах модуля mod_accel. Директива RandomBannersyntax: RandomBanner on|off|строка длинаdefault: нет context: server config, virtual host, location, files Директива указывает искать заданную строку и заменять следующее за ней число случайным числом. Максимальное число заменяемых символов указывается во втором параметре директивы. При этом идущие подряд одинаковые числа будут меняться на одинаковые случайные числа. Например, директивы заменит текстRandomBanner random=rb 10 RandomBanner rand= 10 <a href="http://host/path0?place=1&random=rb00000"> <img src="http://host/path1?place=1&random=rb00000"> </a> <a href="http://host/path0?place=1&key=1234"> <img src="http://host/path1?place=1&key=1234&rand=11111"> </a> <a href="http://host/path0?place=1&random=rb00000"> <img src="http://host/path1?place=1&random=rb00000"> </a> на такой: <a href="http://host/path0?place=1&random=rb42943"> <img src="http://host/path1?place=1&random=rb42943"> </a> <a href="http://host/path0?place=1&key=1234"> <img src="http://host/path1?place=1&key=1234&rand=31520"> </a> <a href="http://host/path0?place=1&random=rb06172"> <img src="http://host/path1?place=1&random=rb06172"> </a> Модуль mod_quoted
Модуль mod_quoted перекодирует русские символы в ответах
модуля mod_accel, представленные в виде quoted printable,
в конструкциях вида '<a href="/show?page=2&word=%80%81%82">'.
Такие конструкции обычно используются при выдаче результатов
поиска для ссылок на оставшиеся страницы с результатами поиска.
Символы перекодируются только в ссылках вида
Директива RecodeQuotedsyntax: RecodeQuoted on|offdefault: off context: server config, virtual host, location, files Директива разрешает или запрещает перекодирование quoted printable символов. Модуль mod_freezeМодуль mod_freeze замораживает слишком активные теги и параметры в ответах модуля mod_accel:
Директива FreezeStartsyntax: FreezeStart строкаdefault: нет context: server config, virtual host, location, files compatibility: mod_accel 1.0.22 и выше Директива задаёт строку, после которой замораживаются теги и параметры. По умолчанию замораживание начинается с самого начала ответа. До версии mod_accel 1.0.23 по умолчанию замораживание начиналось после тэга body. Кроме того, директиву можно было задать только глобально для всего сервера. Директива FreezeTagssyntax: FreezeTags on|offdefault: off context: server config, virtual host, location, files compatibility: mod_accel 1.0.22 и выше Директива разрешает или запрещает изменение тегов. Взаимодействие с модулем mod_rewrite
Хотя при установке mod_accel модуль mod_proxy продолжает работать,
это не относится к флагу P директивы
RewriteRule модуля mod_rewrite,
если, конечно, модуль mod_accel не был сконфигурирован с параметром
При использовании mod_accel можно использовать в директиве RewriteRule флаги MC, MW и MP, как в директиве AccelPass: за одним исключением в флаге MP нельзя использовать значение L.RewriteRule ^/one.html$ http://backend/$1 [P,MC=10,MP=Tsome] Поддержка флага MP в директиве RewriteRule появилась в mod_accel, начиная с 1.0.6. В более ранних версиях ресурс можно ограничивать только именем бэкенда. Первый параметр директивы RewriteRule можно использовать в SSI, например: <!--#include virtual="/one.html?arg=one" --> Полная поддержка директивы RewriteRule обеспечена в mod_accel, начиная с версии 1.0.5. Начиная с mod_accel версии 1.0.10, с помощью директивы AccelReverse можно корректировать заголовки "Location" и "Refresh": AccelReverse / http://backend/ Начиная с mod_accel версии 1.0.29, при проксировании с помощью модуля mod_rewrite можно переписывать заголовок "Location" и "Refresh" с помощью этого же модуля. Например, запрос "http://frontend/one/test" с помощью директивы будет направлен на "http://one.backend/test". Если "test" окажется каталогом, то бэкенд вернёт редирект на "http://one.backend/test/". Это редирект можно переписать на фронтенде, указав имя бэкенда при тестировании переменной среды "ACCEL_REWRITE":RewriteRule ^/([^/]+)/(.*)$ http://$1.backend/$2 [P,L] Правила, переписывающие заголовки "Location" и "Refresh", должны идти перед правилами, описывающими проксирование.RewriteCond %{ENV:ACCEL_REWRITE} ^([^.]+)\.backend$ RewriteRule ^(.*)$ http://frontend/%1/$1 [P,L] RewriteRule ^/([^/]+)/(.*)$ http://$1.backend/$2 [P,L] Начиная с версии 1.0.30, вышеописанная процедура с модулем mod_rewrite разрешается с помощью директивы AccelModRewriteLocation. Настройка производительностиИспользование директив AccelIgnoreNoCache, AccelIgnoreAuth, AccelBusyLock, AccelMaxStale и ограничение числа соединений позволяет уменьшить нагрузку на бэкенд, отдавая закэшированные ответы.
Увеличение размера буфера приёма данных от бэкенда директивой
AccelBkRcvBuffSize позволяет избежать
использования временного файла в качестве буфера.
Для кэшируемых ответов это не так критично, поскольку
этот же временный файл впоследствии будет перелинкован в файл кэша.
Если размер ответа превышает размер буфера в памяти,
то в ErrorLog пишется предупреждение:
Установка директивы AccelUnlinkNoCached в состояние off позволяет не считать хэш-функцию md5 для запросов, которые точно не будут кэшироваться. Поскольку системные вызовы являются достаточно дорогостоящими операциями, то минимизация их числа ведёт к увеличению производительности системы. Рассмотрим способы уменьшения числа системных вызовов при работе mod_accel. Если фронтенд и бэкенд соединены ethernet'ом, то ответ зачастую читается блоками по 1460 байт или блоками размером кратным 1460. В этом случае ответ размером 20K может быть прочитан за 10-15 пар системных вызовов select() и read(). Если же с помощью директивы AccelWaitBeforeBodyRead подождать 200-300 миллисекунд прежде, чем читать тело ответа, то, вполне вероятно, что ядро за это время примет если не весь ответ, то хотя бы его большую часть, и ответ будет прочитан всего за одну или несколько пар системных вызовов select() и read(). Разумеется, ядро не сможет принять весь ответ за раз, если размер его буфера меньше размера ответа, поэтому, возможно, нужно будет увеличить размер TCP-буфера приёма в ядре директивой AccelBkRcvSockBuffSize. Кроме того, для того, что бы весь ответ был прочитан из TCP-буфера ядра за один раз необходимо, что бы размер буфера, задаваемый директивой AccelBkRcvBuffSize был не меньше размер буфера TCP-буфера ядра. Проанализировать действие вышеописанных директив можно с помощью заметок "accel_bnr", "accel_bfr", "accel_br", в которых записывается соответственно число чтений бэкенда, размер заголовка ответа и части ответа, считанной за первое чтение, и полный размер ответа. Увеличение размера буфера отправки данных клиенту директивой AccelSendSize позволяет уменьшить число системных вызовов select() и write(). Необходимо заметить, что select() используется только в случае, когда параллельно с отправкой данных клиенту происходит чтение ответа от бэкенда. Если же ответ полностью считан, то используется только блокирующий write(). Увеличение размера буфера отправки данных клиенту директивой AccelCacheSendSize позволяет уменьшить число системных вызовов read() для чтения ответа из кэша и write() для отправки данных клиенту. Параметр noauto в директиве AccelCacheRoot позволяет не делать системных вызовов mkdir() для создания промежуточных каталогов при каждом создании нового файла кэша. Как mod_proxy взаимодействует с бэкендомХотя модуль mod_proxy часто используется как буфер между тяжёлым сервером (mod_perl) и медленным клиентом, он плохо справляется с этой задачей. Это связано с тем, что mod_proxy читает ответ от бэкенда блоками по 8K и такими же блоками отдаёт его клиенту. После получения всего ответа mod_proxy вызывает функцию ap_bflush(), которая записывает оставшиеся данные из внутреннего буфера Apache размером 4K в сокет клиента. И лишь после этого mod_proxy закрывает сокет бэкенда. Если в качестве бэкенда используется Apache, то после передачи всех данных фронтенду, он выполняет функцию lingering_close() делает shutdown() на запись в сокет и, подождав в select()'е 2 секунды, закрывает сокет. Таким образом, вся буферизация по сути выполняется не mod_proxy, а ядром и зависит только от размеров TCP-буферов приёма и отправки в ядре на машине с mod_proxy и от размера TCP-буфера отправки на бэкенде. Рассмотрим варианты ситуаций при работе с медленным клиентом (скорость около 3K/s), которые могут возникнуть на FreeBSD версии 3.0-4.3, где размер этих буферов по умолчанию равен 16K.
Надо сказать, что эти дополнительные 2 секунды в Apache нигде не
фиксируются, то есть, их нельзя увидеть в логах во времени выполнения
запроса - %T и в запросе server-status, так как время, затраченное
на lingering_close(), в %T не учитывается и процесс помечается как
свободный в scoreboard ещё до вызова lingering_close().
Единственный способ увидеть эти две секунды - это запустить
команду
Уменьшить время ожидания бэкенда при записи больших ответов можно с помощью
директивы ProxyReceiveBufferSize задающей размер TCP-буфера
приёма в ядре, и SendBufferSize задающей размер TCP-буфера
отправки в ядре.
Кроме того, можно увеличить размеры всех TCP-буферов
на фронтенде и бэкенде средствами операционной системы.
Однако увеличение буфера отправки на фронтенде лишь отдаляет проблему
2-х секундной задержки.
Избежать 2-х секундной задержки можно, если собрать бэкенд с параметром
В Apache 1.3.24 частично решена проблема взаимодействия mod_proxy и бэкенда появилась директива ProxyIOBufferSize, позволяющая задать размер буфера для получения ответа от бэкенда. Кроме того, если от бэкенда получен весь ответ, то соединение с ним закрывается, что позволяет избежать 2-х секундной задержки. Тем не менее, проблема решена не полностью если размер ответа бэкенда будет больше суммы размера заданного буфера и ядерных TCP-буферов, то бэкенд будет занят на время, необходимое для передачи части ответа, превышающей суммарный размер буферов. Кроме синхронного получения ответа ответа от бэкенда и отдачи его клиенту, mod_proxy так же синхронно принимает тело запроса клиента и передаёт его бэкенду. При использовании mod_accel такой проблемы нет, поскольку чтение из сокета бэкенда и запись в сокет клиента выполняются асинхронно, все операции неблокирующие и готовность обоих сокетов проверяется с помощью select()'a. mod_accel считывает ответ от бэкенда в буфер, размер которого задаётся директивой AccelBkRcvBuffSize. Если размер ответа превышает размер буфера, то содержимое буфера записывается во временный файл. Если ответ кэшируемый, то этот временный файл позже перелинковывается в файл кэша. Кроме того, имеется директива AccelBkRcvSockBuffSize, которая так же, как и ProxyReceiveBufferSize позволяет задавать размер TCP-буфера приёма в ядре с тем отличием, что размер задаётся в килобайтах, а не в байтах. Однако в mod_accel она предназначена для уменьшения количества системных вызовов select() и read(), необходимых для чтения ответа бэкенда. Что касается тела запроса, то оно полностью принимается от клиента и только после этого передаётся бэкенду. Размер буфера для приёма задаётся директивой AccelRequestBuffSize. Если тело запроса больше размера буфера, то оно записывается во временный файл. (C) Игорь Сысоев |