The Apache Modeling Project. Глава 3 (Часть 1)


3 HTTP сервер Apache

3.1 Обзор

3.1.1 История

Начало

Apache является потомком веб-сервера NCSA, спроектированного и разработанного Робом Маккулом (Rob McCool). На рынке серверов NCSA позиционировался как сервер для сложных и высокопроизводительных серверных комплексов. Множество же людей хотели простой и компактный сервер, который подходил бы для небольшого веб-сайта. Тем не менее, Роб Маккул не смог продолжать свою работу над сервером NCSA. Он покинул проект и прекратил работу над сервером. Однако, на тот момент сервер NCSA использовали уже множество людей. Как и в случае с другими программами, пользователи изменяли сервер под свои нужды, а также исправляли найденные ошибки. В 1995 году Брайн Бехлендорф (Brian Behlendorf) начал собирать все эти изменения и дополнения и основал рассылку, которая предназначалась для обмена этими дополнениями. Группа из 8 человек, которые составили костяк сообщества этой рассылки, выпустили первую версию сервера Apache. По своей природе, как состоящий из “патчей” и расширений сервера NCSA, свое имя Apache получил от выражения “пропатченный сервер” (”a patchy server”).

Развитие

Первой выпущенной версией сервера стала 0.6.2. Один из членов постоянно растущей группы разработчиков, Роберт Тау (Robert Thau), спроектировал новую архитектуру сервера, которая была представлена в версии 0.8.8. 1 Декабря 1995 года был выпущен Apache версии 1.0 и всего год потребовался на то, чтобы Apache стал более популярным, чем сервер NCSA.

В течение следующих лет группа продолжала расти, а Apache получил множество новых возможностей и был перенесен на различные операционные системы.
В 1999 году группа основала Apache Software Foundation в форме некоммерческой организации. В Марте 2000 года впервые состоялось ApacheCon - конференция разработчиков Apache.

Apache 2

На конференции ApacheCon в Марте 2000 года был впервые публично представлен сервер Apache версии 2.0. Вторая версия Apache представила полностью новую архитектуру сервера. Apache 2.0 стал легче переноситься на различные платформы и стал настолько модульным, что даже перестал быть по настоящему веб-сервером. При разработке соответствующего модуля, ядро Apache 2.0 можно использовать в любом сетевом сервере.
Сегодня обе версии Apache (версия 1.3 и версия 2.0) продолжают существовать. Хотя все и подталкивает на использование новой версии, многие продолжают использовать версию 1.3, которая до сих пор разрабатывается и поддерживается.
Для получения большей информации об истории Apache посетите сайт проекта Apache History по адресу http://www.apache.org/history/.

3.1.2 Особенности

Обе используемые сегодня версии Apache формируют крупнейший рынок веб-серверов. Даже не смотря на то, что Apache является свободно распространяемым сервером, все-таки главной причиной успеха Apache является его широкие функциональные возможности.
Рисунок 3.1: HTTP сервер Apache в своем окружении
Рисунок 3.1: HTTP сервер Apache в своем окружении (Полный рисунок)
Сервер Apache поддерживает одновременную работу и, следовательно, может обслуживать большое количество клиентов. Количество клиентов, которое может одновременно обслуживаться, ограничивается лишь используемыми аппаратными средствами и операционной системой. Сервер может быть легко сконфигурирован с помощью редактирования текстовых файлов или, используя один из многочисленных инструментов с графическим интерфейсом. В соответствии со своей модульной архитектурой, множество возможностей, которые необходимы для работы некоторых приложений, могут быть реализованы в виде дополнительных модулей Apache. Для поддержки такой возможности для разработчиков модулей реализован хорошо документированный API. Модульность и существование множества бесплатных модулей позволяет легко создать мощный веб-сервер без изменения его исходного кода. Используя на сервере множество доступных скриптовых языков, можно легко создать любое веб-приложение. Для использования любого скриптового языка необходим только соответствующий подключаемый модуль. Также обе версии Apache полностью совместимы с HTTP 1.1. Для большинства популярных платформ сделана простая процедура установки сервера. Диаграмма на рисунке 3.1 показывает HTTP сервер Apache в своем окружении. По сравнению с простым HTTP сервером, показанном на рисунке 2.1, тут мы видим администратора, который работает с файлами конфигурации, а также с серверными расширениями, используя CGI или серверный API. Эти расширения могут получить любой ресурс на машине сервера или на удаленной машине через сеть.

3.2 Использование Apache

3.2.1 Конфигурирование Apache

Так как использование и администрирование Apache рассмотрено во множестве других источниках, этот документ даст лишь обзор этого аспекта, необходимый для понимания работы Apache в целом.
Вот основные 4 пути конфигурирования Apache:
  1. Сборка/Установка
    Конфигурирование Apache путем выбора модулей, установки флагов компилятора, используемых для сборки, выбора путей установки и прочего.
  2. Параметры командной строки
    Конфигурирование Apache при старте. Все возможные параметры командной строки могут быть найдены в книге Apache 2 Bible, которую можно заказать в Озоне.
  3. Файлы глобальной конфигурации
    Apache использует файл глобальной конфигурации, который обрабатывается при запуске сервера. По умолчанию он называется httpd.conf и находится в каталоге conf/ внутри корневого каталога сервера.
  4. Локальные файлы конфигурации
    Также Apache может быть сконфигурирован с помощью локальных файлов конфигурации .htaccess. Эти файлы просматриваются при обработке запроса, когда Apache обходит каталоги файловой системы при поиске запрошенного документа. Например, они помогают авторам сконфигурировать свое веб-пространство по собственному усмотрению.
Рисунок 3.2: Конфигурирование HTTP сервера Apache через конфигурационные файлы
Рисунок 3.2: Конфигурирование HTTP сервера Apache через конфигурационные файлы (Полный рисунок)
Последние два пути описывают конфигурирование Apache при помощи текстовых файлов, как это показано на рисунке 3.2. Далее мы рассмотрим структуру файлов конфигурации и дадим пример их использования.

Глобальные и локальные файлы конфигурации

Глобальная конфигурация

Конфигурационные директивы в главном файле конфигурации Apache - httpd.conf сгруппированы в три основные группы:
  1. Директивы, которые контролируют работу сервера Apache в целом (глобальные директивы).
  2. Директивы, которые задают параметры главного сервера. Главный сервер отвечает на запросы, которые не поступили на какой-либо виртуальный хост. Эти директивы также задают значения по умолчанию для всех виртуальных хостов.
  3. Директивы виртуальных хостов.
Директивы, размещенные в главных конфигурационных файлах, влияют на весь сервер в целом. Если вы хотите изменить конфигурацию только для части сервера, вы можете поместить ваши директивы в секции <Directory>, <DirectoryMatch>, <Files>, <FilesMatch>, <Location> и <LocationMatch>. Эти секции ограничивают влияние директив на определенные каталоги файловой системы или на определенные URL.
Секции <Directory> используются для каталогов файловой системы, а секции <Location> применяются для URL запросов.
Apache может обслуживать одновременно множество различных веб-сайтов с разными именами хостов. Этот механизм называется “виртуальные хосты”. Поэтому директивы, помещенные внутрь секций <VirtualHost>, будут применятся только к запросам на определенный сайт.
В глобальном файле конфигурации администратор может разрешить использование локальных файлов конфигурации .htaccess, которые задают директивы для каталога, в котором сами расположены.

Локальная конфигурация

Apache позволяет производить децентрализованное управление конфигурацией через специальные файлы, размещенные внутри дерева каталогов. Они позволяют пользователям конфигурировать свои веб-пространства в рамках, установленных администратором. Для этого существуют специальные файлы .htaccess (но имя может быть изменено директивой AccessFileName).
Так как файлы .htaccess считываются при каждом запросе, то изменения, сделанные в этих файлах, происходят немедленно. Директивы, размещенные в файле .htaccess, распространяются на каталог, в котором находится файл, а также на все вложенные каталоги, переопределяя одноименные директивы, заданные в вышестоящих файлах. Немедленное применение изменений делает эти файлы незаменимыми в случае, когда множество пользователей одновременно используют один сервер Apache. Другое преимущество этих файлов заключается в том, что синтаксическая ошибка в них влияет только на небольшую часть сервера, при этом вся система может продолжать работать.
Два основных недостатка использования .htaccess:
  1. Снижение производительности;
  2. ‘Распыление’ доступа к конфигурационным данным;
Первое отчасти решается здравомыслящим использованием директивы AllowOverride, а последнее остается уделом доверия между пользователями и администратором.

Синтаксис

Директивы конфигурации являются командами для Apache. Есть два типа директив: простые и секционные, которые могут содержать одну или более директив.
Apache обрабатывает файлы конфигурации строка за строкой, читая каждую строку, кроме пустых строк и строк комментариев (начинающихся с символа #). Первое слово в такой строке является именем директивы, тогда как остальные слова воспринимаются как параметры директивы. Чтобы использовать более одной строки параметров для директивы, нужно применить обратный слеш (’\') как последний символ строки, который означает, что параметры продолжаются на следующей строке.
Apache различает несколько контекстов, в которых используются директивы. Каждая директива доступна только в ограниченном множестве контекстов.

Контексты глобальной конфигурации

Серверный контекст применяется в глобальном файле httpd.conf (имя файла может быть изменено с помощью опции в командной строке сервера) и делиться на 5 подконтекстов:
  1. Глобальный контекст, который содержит директивы, применяемые к главному серверу.
  2. (<VirtualHost>) Секции виртуальных хостов содержат директивы, которые применяются к определенному виртуальному серверу.
  3. (<Directory>, <DirectoryMatch>) Секции каталогов содержат директивы, которые применяются к заданному каталогу и ко всем вложенным в него.
  4. (<Files>, <FilesMatch>) Секции файлов содержат директивы, которые применяются к определенным файлам.
  5. (<Location>,<LocationMatch>) Секции URL содержат директивы, которые применяются к определенным URL и их частям.
Директивы, размещенные в главном файле конфигурации, применяются ко всему серверу целиком. Для изменения конфигурации только для части сервера поместите ваши директивы в соответствующий контекст. Некоторые типы секций могут вкладываться друг в друга, создавая тем самым древовидную конфигурацию.

Контексты локальной конфигурации

Контекст каталога применяется и в локальных файлах .htaccess. Внутри их можно использовать директивы для следующих пяти контекстов:
  1. (AuthConfig) Контекст идентификации содержит директивы, контролирующие идентификацию.
  2. (Limits) Контекст ограничений содержит директивы, которые контролируют ограничение доступа.
  3. (Options) Контекст опций содержит директивы, которые контролируют специальные возможности данного каталога.
  4. (FileInfo) Контекст файловой информации содержит директивы, которые контролируют атрибуты документа.
  5. (Indexes) Контекст индексов содержит директивы, которые контролируют индексацию каталога.
Файлы .htaccess имеют такой же синтаксис, как и главные файлы конфигурации. Администратор сервера может ограничить число директив, которые могут использоваться в файлах .htaccess. Для этого используется директива AllowOverride.
Более подробную информацию и список директив можно найти на http://httpd.apache.org/docs/ или в книге Apache 2 Bible, которую можно заказать в Озоне.

Как Apache определяет конфигурацию для запроса?

  1. Определяется виртуальный хост. Находится виртуальный хост, соответствующий URI запроса.
  2. Получается конфигурация для URI.
  3. Изменение URI запроса (например: mod_rewrite). Модули имеют возможность преобразовать URI запроса в некоторое имя файла.
  4. Обход каталогов начинается с корневого (/) каталога, обрабатывая файлы .htaccess. Apache читает конфигурацию каждого каталога при обходе и объединяет их.
  5. Обход файлов для получения конфигурации файлов.
  6. Получение нового местоположения, в случае если URI запроса был изменен.
После того, как Apache определяет, что запрошенный ресурс является файлом, он производит обход каталогов. Для получения необходимой конфигурации, Apache просматривает все секции <Directory>, начиная с файлов глобальной конфигурации. Если при обходе встречаются пересекающиеся директивы, то они объединяются с предыдущими значениями. В результате получаем множество директив, собранное из всех файлов конфигурации сервера.
Поиск файлов .htaccess Apache начинает с вершины файловой системы. Затем спускается вниз по дереву каталогов к нужному документу. При этом он обрабатывает и объеденяет все найденные файлы .htaccess.
При обходе секции объединяются в следующем порядке:
  1. Секции <Directory> (кроме регулярных выражений) и .htaccess сливаются одновременно. Причем директивы .htaccess переопределяют секции <Directory> в главном файле конфигурации.
  2. <DirectoryMatch> и <Directory> с регулярными выражениями.
  3. <Files> и <FilesMatch> объединяются одновременно.
  4. <Location> и <LocationMatch> объединяются одновременно.
Элементы каждой группы обрабатывается в том порядке, в котором они находятся в файлах конфигурации. Только директивы <Directory> обрабатываются в порядке “более короткий путь обрабатывается перед более длинным”. Если множество секций <Directory> применимы для одного каталога, то они обрабатываются в порядке расположения в файле конфигурации. Файлы конфигурации считываются в следующем порядке: httpd.conf, srm.conf и access.conf (srm.conf и access.conf не используются и сохраняются только для совместимости).
Директивы внутри секций <VirtualHost> обрабатываются после внешних директив. Тем самым, виртуальные хосты могут переопределить директивы главного сервера. А более поздние секции переопределяют более ранние.
Для получения большей информации, смотрите разделы 4.4.4 и 4.5

Пример конфигурации

Файл httpd.conf:
#########################################
# Секция 1: Глобальные настройки
# Многие директивы имеют значения по умолчанию, поэтому многое было опущено

ServerType standalone
ServerRoot “/etc/httpd”
Listen 80
Listen 8080
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
MinSpareServers 5
MaxSpareServers 10
StartServers 5
MaxClients 150
MaxRequestsPerChild 0
#########################################
# Секция 2: Конфигурация главного сервера

ServerAdmin webmaster@foo.org
ServerName www.foo.org
DocumentRoot “/var/www/html”
# серьезное ограничение для всех директив
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory “/var/www/html”>
Options Indexes
FollowSymLinks MultiViews AllowOverride None
Order allow,deny
Allow from all
</Directory>
#########################################
# Секция 3: Виртуальные хосты

<VirtualHost www.foo.dom:80>
# все хосты домена hpi.uni-potsdam.de доступны
# все остальные хосты закрыты

<Directory />
Order Deny,Allow
Deny from all
Allow from hpi.uni-potsdam.de
</Directory>
# директива “Location” обрабатывается только если модуль
# mod_status встроен в сервер

<IfModule mod_status.c>
<Location /server-status>
SetHandler server-status
Order Deny,Allow
Deny from all
Allow from .foo.com
</Location>
</IfModule>
</VirtualHost>

3.3 Расширение Apache: Модули Apache

3.3.1 Введение

Модуль - это программный код, который используется для расширения функциональности HTTP сервера Apache. Модули либо статично включены в ядро сервера, либо подгружаются динамически. Для статичного включения код модуля должен быть добавлен в исходный код сервера и скомпилирован вместе с ним. Динамически подключаемые модули добавляют функциональность серверу после своей загрузки. Они загружаются как динамические библиотеки в процессе запуска или перезагрузки сервера. Такое возможно благодаря модулю mod_so, который предоставляет функции для динамического добавления модулей. В текущей версии Apache 2.0 и Apache 1.3 вся функциональность, кроме самой основной, находится в модулях.
Модули взаимодействуют с сервером Apache через простой интерфейс. Они регистрируют в Apache свои обработчики хуков. При необходимости (когда срабатывает хук) ядро Apache вызывает все зарегистрированные в нем обработчики. Также модули могут взаимодействовать с ядром сервера через Apache API. Используя этот API, каждый модуль может получить доступ к структурам данных сервера, например, для отправки данных или для выделения памяти.
Каждый модуль содержит информацию о себе, в которой содержатся данные об обработчиках модуля и данные о директивах, которые он обрабатывает. Эта информация хранится в структуре module AP_MODULE_DECLARE_DATA. Данная структура необходима при регистрации модуля в ядре сервера.
Все процессы сервера Apache, будь это главный сервер или дочерние, содержит исполнительный код. Процесс Apache состоит из ядра, статичных и динамических модулей.
Рисунок 3.3: Структура модуля Apache 2
Рисунок 3.3: Структура модуля Apache 2 (Полный рисунок)
Рисунок 3.4: Взаимодействие ядра Apache и модулей
Рисунок 3.4: Взаимодействие ядра Apache и модулей (Полный рисунок)
Как видно на рисунке 3.4, модули и ядро могут взаимодействовать двумя способами. Ядро сервера может вызывать зарегистрированные в ядре обработчики модулей. А модули могут использовать Apache API, а также могут считывать и изменять важные структуры данных сервера, такие как запись запроса/ответа - request_rec.

3.3.2 Типы обработчиков

Модуль может реализовывать различные типы обработчиков:
  • Обработчики хуков.
  • Обработчики директив конфигурации.
  • Фильтры.
  • Необязательные функции.

Обработчики хуков

Хук - это некоторый момент, когда управление передается на зарегистрированный обработчик. Это подобно переключению по событию, результатом которого является выполнение обработчика. Реализует хук функция ap_run_HOOKNAME, которая имеет название срабатываемого хука.
Можно выделить два типа вызовов обработчиков хуков:
RUN_ALL/VOID: Ядро вызывает все зарегистрированные обработчики, не обращая внимания смогут ли они выполнить задачу или откажутся выполнять ее.
RUN_FIRST: Ядро вызывает зарегистрированные обработчики до тех пор, пока очередной обработчик не выполнит задачу или не произойдет ошибка.
Пока модуль не зарегистрирует свои обработчики в ядре сервера, ядро не сможет вызвать их. Регистрация обработчиков у Apache 1.3 и Apache 2.0 отличается. Apache 1.3 предоставляет 13 предопределенных хуков. Регистрация обработчиков модуля происходит автоматически в ядре при чтении структуры модуля во время его загрузки. В Apache 2.0 структура модуля содержит ссылки только на 4 обработчика предопределенных хуков, используемых для работы с конфигурацией. Все остальные обработчики регистрируются с помощью функции register_hooks. Такой подход позволяет создавать новые хуки без изменения интерфейса модуля Apache. Также модуль может предоставлять новые хуки, обработчики которых могут регистрировать другие модули.
Рисунок 3.5 показывает как хуки и обработчики взаимодействуют между собой: Хук ABC определен некоторым макросом (AP_DECLARE_HOOK и т.п. см. внизу рисунка) Результатом этого макроса является создание регистрирующей процедуры ap_hook_ABC. Хук вызывает процедуру ap_run_ABC, которая считывает реестр обработчиков хука, в котором хранится информация обо всех зарегистрированных обработчиках хука, модулях этих обработчиков и их последовательности. Структура модуля наверху рисунка указывает на процедуру регистрации обработчиков хука - register_hooks, которая регистрирует обработчики хуков, вызывая процедуры ap_hook_xxx.
Рисунок 3.5 Механизм хуков сервера Apache 2
Рисунок 3.5 Механизм хуков сервера Apache 2 (Полный рисунок)
Внизу рисунка изображен агент “контроллер обработки запросов”. Он приводит к срабатыванию хуков, вызывая процедуры ap_run_xxx, которые в свою очередь считывают реестр обработчиков хука и вызывают все или один из зарегистрированных обработчиков.
Очень важен порядок вызовов обработчиков хука. В Apache 1.3 порядок регистрации модулей определяет порядок вызовов обработчиков. Порядок можно изменить в конфигурационном файле, но он является одинаковым для всех 13 хуков. В Apache 2.0 все изменилось. Реестр хуков может хранить индивидуальный порядок вызовов обработчиков для каждого хука. Используя процедуру регистрации обработчика хука ap_hook_xxx, модуль может задать требования к своему положению в последовательности вызовов. Это может быть или имя модуля, чьи обработчики должны быть вызваны перед или после, или он может попытаться получить первую или последнюю позицию в последовательности вызовов.

Обработчики директив конфигурации

Модуль может предоставлять собственный набор директив, которые можно использовать в файлах конфигурации. После считывания директивы, конфигурационный процессор ядра предоставит ее соответствующему обработчику, который должен быть зарегистрирован для этой директивы. На рисунке 3.5 структура модуля содержит обработчики для работы с конфигурацией модуля (create-dir_config, merge_dir_config) и таблицу директив, которая содержит все директивы модуля и указатели на их обработчики.
Обработчики для работы с конфигурацией предназначены для выделения памяти под конфигурацию и для объединения конфигураций разных уровней при обработке запроса.

Необязательные функции

Модуль Apache 2.0 также может регистрировать фильтры и необязательные функции. Необязательные функции похожи на хуки. Отличие заключается в том, что ядро игнорирует любое возвращаемое значение необязательной функции. Ядро вызывает все необязательные функции модуля, несмотря на возращаемый ими результат. Поэтому необязательные функции можно использовать для задач, которые не являются критичными для обработки запросов/ответов.

3.3.3 Обработка контента

Наиболее важным моментом в цикле ‘запрос-ответ’ является вызов обработчика контента, который отвечает за отправку данных клиенту.
В Apache 1.3 обработчик контента похож на все остальные обработчики. Для определения обработчика, который необходимо вызвать, Apache 1.3 использовал обработчик type_checker, который связывал запрошенный ресурс с MIME типом или обработчиком. После этого ядро Apache вызывает этот обработчик контента, который и отвечает за успешное формирования ответа. Этот обработчик может отсылать данные клиенту напрямую. Все это делает обработку запроса довольно простой задачей, но при этом имеет свои недостатки, напрмер, только один модуль мог принять участие в обработке запроса. Если для ресурса будет задан более чем один обработчик, вызовется обработчик, который был зарегистрирован первым. Также невозможно, чтобы один обработчик мог модифицировать результат другого (без внесения изменений в исходный код сервера).
Apache 2.0 расширил механизм обработчиков контента с помощью выходных фильтров. Как в версии 1.3, так и во второй версии сервера для отправки запрошенного ресурса может быть вызван только один обработчик контента. Но во второй версии для изменения данных, отсылаемых обработчиком контента, можно использовать фильтры. Поэтому множество модулей могут принять участие в обработке одного запроса. Каждый MIME тип ресурса может быть связан с различным множеством фильтров и различным порядком их вызова. Такие последовательности вызовов фильтров называются цепочками выходных фильтров.
При вызове обработчика контента Apache 2.0 создает цепочку выходных фильтров. В этой цепочке фильтр выполняет некоторые действия над данными, а по завершению, передает их следующему фильтру. Такой подход позволяет нескольким модулям вместе формировать один ответ. Примером этого является обработчик CGI контента, который передает теги серверных вставок (SSI) вниз по цепочке фильтров, чтобы модуль SSI мог их обработать.

Опубликовано в: Архитектура Март 12, 2006

3 Комментариев »

  1. АВТОРА ЄТОГО САЙТА Вы не перестаете меня удивлять! СУПЕР СТАТЬЯ ! РЕСПЕКТ
    _____________________
    /go.php?url=/go.php?url=http://www.flybirds.ru/

    Комментарий от андрюха — Август 29, 2008 @ 4:31 pm

  2. Я использую эту книгу The Traditional Bowyer’s Bible.Супер.
    Можно посмотреть здесь здесь

    Комментарий от Сергей — Январь 19, 2009 @ 8:58 pm

  3. обработчик type_checker, который связывал запрошенный ресурс с MIME типом или обработчиком - в не ошиблись?

    Комментарий от Богдан — Апрель 10, 2009 @ 1:16 pm

Оставить комментарий

You must be logged in to post a comment.

© apachedev.ru, 2005-2011