LXF85:Apache

Материал из Linuxformat.

Перейти к: навигация, поиск

ЧАСТЬ 2: Если бы Apache умел только отдавать статические html-файлы, разве бы он был столь популярен? К счастью, Apache способен на гораздо большее... Сегодня Сергей Супрунов научит вас поддерживать динамические web-сайты

Содержание

Apache – друг «бледнолицых»

Apache
Коротко о модулях

mod_asis – позволяет отправлять клиенту файлы в «сыром» виде, без добавления каких-либо заголовков (полезен, если вы хотите сами сформировать нестандартные заголовки).

mod_dav – поддержка протокола WebDAV, позволяющего работать с файлами по протоколу HTTP.

mod_imap – поддерживает работу «серверных» карт изображения (Image Map), когда щелчок пользователя по той или иной области рисунка обрабатывается сервером по-своему.

mod_rewrite – предоставляет широчайшие возможности по перезаписи URL-адресов; например, вы можете перенаправлять запросы на другие ресурсы, используя регулярные выражения для определения правил подстановки.

mod_speling – автоматически исправляет ошибки в имени ресурса, подбирая наиболее подходящие варианты (например, если файла inex.html нет, пользователю будет возвращён index.html).

mod_ssl – обеспечивает работу по защищённому протоколу SSL.mod_suexec – позволяет выполнять CGI-сценарии с правами другого пользователя, а не того, от имени которого работает Apache.

mod_vhost_alias – позволяет задавать «шаблоны» виртуальных хостов, что полезно при настройке большого числа виртуальных сайтов со схожими параметрами.

Как упоминалось в первой части, Apache разработан по модульному принципу. Модули позволяют наращивать функциональность практически до бесконечности. Во многие дистрибутивы включается до 40–50 модулей, покрывающих основные потребности, но их число этим, естественно, не ограничивается. Модули могут быть либо вкомпилированы в основной двоичный файл (httpd, Apache, Apache2, в зависимости от дистрибутива), либо собраны для динамического подключения. Список первых можно получить по команде httpd -l (опять-таки с поправкой на имя), вторые могут располагаться либо в базовом каталоге web-сервера в modules, либо в /etc/Apache2/mods-available, /usr/lib/Apache2/modules и т.п. Обычно список имеющихся в дистрибутиве модулей можно узнать из конфигурационного файла Apache по строкам LoadModule.

Например, рассмотренная в прошлый раз возможность размещать странички пользователей в их домашних каталогах обеспечивается модулем mod_userdir. За автоматическое построение индекса каталога отвечает mod_autoindex (зачастую компилируется вместе с сервером). Заметьте, что если вы хотите динамически подгружать модули, Apache должен быть статически собран с модулем mod_so – именно он отвечает за подключение дополнительных модулей «на лету».

Ещё один часто используемый и потому обычно собираемый статически модуль – mod_alias. Его зона ответственности, как следует из названия – псевдонимы для тех или иных каталогов. Например, вы можете указать:

Alias /files /mnt/cdrom

Теперь при запросе http://www.yourserver.ru/files/my.mp3 web-сервер будет искать нужный файл в каталоге /mnt/cdrom. Не забывайте только, что первым параметром указывается путь от корня сайта, вторым – от корня файловой системы.

О некоторых других модулях коротко сказано во врезке, а подробности ищите в документации (начните поиск со страницы http://httpd.Apache.org/docs/2.2/mod/).

Будьте динамичнее: основы CGI

До этого мы работали только со статическими страницами. Однако это лишь небольшой процент тех возможностей, которые предоставляют нам web-технологии. Сайт, не позволяющий оставить своё мнение в гостевой книге или хотя бы просто зарегистрироваться, чтобы при следующем посещении получить адресованное лично вам «Здрассте» смотрится в современном мире по меньшей мере скучно.

Одной из первых технологий, которые наделяют сайт способностью к взаимодействию с пользователем и позволяют динамически создавать содержимое в зависимости от тех или иных условий, является Common Gateway Interface (CGI). CGI позволяет серверу не просто «выплеснуть» в сокет содержимое файла, а запустить исполняемую программу и вернуть клиенту её вывод. Реализован этот функционал в модуле mod_cgi.

Например, клиент запрашивает ресурс http://www.server.ru/cgi-bin/gbook.cgi. Если в настройках сервера каталог cgi-bin определён как предназначенный для запуска CGI-сценариев, то сервер запустит файл gbook.cgi, передав через переменные окружения и входной поток информацию из клиентского запроса. Сценарий выдаст в свой стандартный поток STDOUT информацию (как правило, html-страницу), которую сервер перешлёт клиенту.

По умолчанию (практически во всех дистрибутивах), Apache уже настроен на выполнение CGI-сценариев в некотором особом каталоге. Имя этого каталога вы найдёте в конфигурационном файле в строке директивы ScriptAlias (в Ubuntu это /usr/lib/cgi-bin). Любой файл из этого каталога, к которому выполняется запрос, Apache запускает в специально созданном для этого окружении (сам сценарий должен иметь права на выполнение), а всё, что сценарий выведет операторами print (или аналогичными), будет отдано клиенту.

Для каталога, указанного в ScriptAlias, должна быть задана опция ExecCGI (директивой Options +ExecCGI). При желании обрабатывать CGI-сценарии вне данного каталога, можно сопоставить соответствующий обработчик с тем или иным расширением:

AddHandler cgi-script .cgi

Есть ещё одна директива, включающая обработку CGI – SetHandler cgi-script. Будучи указанной в одной из секций, она заставит Apache рассматривать все подпадающие под действие секции файлы в качестве CGI-скриптов. Фактически, упомянутая выше директива ScriptAlias аналогична следующим строкам:

Alias /cgi-bin /usr/lib/cgi-bin
<Directory /usr/lib/cgi-bin>
SetHandler cgi-script</Directory>

По соображениям удобства сопровождения [и безопасности, – прим. ред.], не рекомендуется размещать CGI-сценарии за пределами отдельного каталога, выделенного специально для них.

Для разработки CGI-сценариев вы можете использовать любой удобный вам язык программирования – нужно только, чтобы система умела работать с ним, а он сам – поддерживал минимум необходимых средств (например, чтение данных из входного потока и переменных окружения).

Ещё быстрее: FastCGI

Технология CGI очень хороша своей универсальностью и гибкостью, но имеет один существенный недостаток, особенно сильно сказывающийся при работе с языками сценариев типа Perl, Python, Ruby – низкое быстродействие. Ведь при каждом запросе будет запускаться интерпретатор соответствующего языка, выполняться компиляция текста сценария в байт-код и только после этого – выполняться сценарий. Затем все эти ресурсы нужно ещё и высвободить. В режиме web-сервера такие накладные расходы могут доходить до 80–90% от общих затрат времени на обслуживание запроса [это становится особенно актуально для инструментариев типа Ruby On Rails, – прим. ред.].

Для решения этой проблемы был разработан интерфейс FastCGI. В отличие от CGI, здесь сценарий постоянно находится в памяти (т.е. запуск интерпретатора и компиляция требуются только при первом запуске; есть возможность настроить предварительную компиляцию при старте сервера), а вместо переменных окружения и потоков ввода-вывода взаимодействие с web-сервером осуществляется через двунаправленное соединение.

Чтобы это работало, сценарий должен быть написан соответствующим образом (в частности, не закрывать соединение после выполнения, а возвращаться к ожиданию следующего запроса).

Для работы с FastCGI нужно, во-первых, установить модуль mod_fastcgi. Если ваш менеджер пакетов ничего о нем не знает, это можно сделать и вручную, скачав архив с сайта www.fastcgi.com. Следуйте инструкциям в README и INSTALL (для Apache 2.0 – INSTALL.AP2). Для успешной сборки вам понадобятся исходные коды Apache. Если у вас Apache 2.2, то придётся наложить патч, например, отсюда: http://www.fastcgi.com/archives/fastcgidevelopers/2005-December/004060.html.

Во-вторых, в конфигурации Apache нужно указать такие директивы:

LoadModule fastcgi_module modules/mod_fastcgi.so
<IfModule mod_fastcgi.c>
     AddHandler fastcgi-script .fcgi
     SocketPath /var/lib/аpache2/fcgid/sock
</IfModule>
Листинг test.fcgi
#!/usr/bin/perl
use FCGI;
$cnt = 0;
while(FCGI::accept >= 0) {
   $cnt++;
   print "Content-Type: text/html\n\n";
   print "Это ${cnt}-й запрос ресурса";
}

Не забудьте исправить пути на свои. В данном примере с файлами, имеющими расширение fcgi, будет сопоставлен обработчик fastcgiscript. Теперь можно создать сценарий, подобный test.fcgi, приведенному во врезке слева.

Неоднократно запуская этот сценарий, вы убедитесь, что он постоянно присутствует в памяти – переменная $cnt будет наращиваться с каждым новым запросом. Обратите внимание на обязательность включения модуля FCGI.

Нужно заметить, что поскольку FastCGI-сценарий не выгружается из памяти, к его качеству предъявляются гораздо большие требования. Например, утечка памяти из-за небрежно написанного кода, совершенно не критичная для обычного CGI-скрипта, может привести к захвату всех доступных ресурсов и фактическому блокированию дальнейшей работы. Также следует избегать глобальных переменных, так что будьте внимательны.

Помимо «официальной» реализации – mod_fastcgi – можно найти и другие. Например, в репозиториях Ubuntu доступен mod_fcgid, совместимый с mod_fastcgi.

Модули специального назначения

Server Side Includes

Если возможности CGI для решения ваших задач избыточны, можно использовать механизм «серверных включений» – SSI (Server Side Includes). Заключается он в том, что в html-код включаются специальные ssi-директивы, а Apache, прежде чем выдать страницу клиенту, заменяет эти директивы результатом их выполнения. Для использования SSI нужно разрешить этот механизм с помощью Options +Includes (IncludesNoExec для большего уровня безопасности, без права запуска внешних программ) и установить выходной фильтр для расширений, которые должны обрабатываться, с помощью AddOutputFilter Includes .shtml (можно использовать SetOutputFilter Includes для «привязки» фильтра ко всем файлам текущей секции). В Apache 1.3 используется директива AddHandler server-parsed .shtml.

Второй путь преодолеть проблемы производительности CGI – специализированные модули, взаимодействующие с Apache API и отвечающие за выполнение сценариев на том или ином языке. К таковым относятся mod_perl, mod_python, mod_php и т.д. Здесь уже сам модуль выполняет интерпретацию сценария (т.е. отдельно запускать Perl или Python не требуется), а за счёт кэширования единожды откомпилированный сценарий может быть сохранён в памяти и будет находиться в полной боевой готовности. При этом со стороны сценария не требуется какой-то специальный код, и во многих случаях в среде mod_* без проблем будут исполняться и обычные CGI-скрипты (хотя определённые ограничения есть и здесь – например, в случае mod_perl нельзя использовать директивы require, _DATA_ и _END_, функцию exit(); требуется также осторожность при работе с глобальными переменными, поскольку они сохраняют свои значения между запусками).

Но платить за это приходится потерей универсальности – очевидно, что mod_python не сможет обработать ваш Perl-скрипт, а для менее распространённых языков может вообще не оказаться модуля.

Эти модули настраиваются аналогично рассмотренным выше – либо с помощью AddHandler по расширению, либо – SetHandler для всех файлов в секции. Естественно, предварительно модуль должен быть подключен с помощью LoadModule. Каждый модуль предоставляет и дополнительные параметры, позволяющие более гибко использовать его возможности. Например, mod_perl позволяет задать тип обработчика. Строка PerlHandler Apache::Registry обеспечивает однократную компиляцию сценариев, которые в дальнейшем постоянно присутствуют в памяти. PerlHandler Apache::PerlRun включит другой обработчик, который позволяет исполнять даже CGI-сценарии, не работающие в окружении Apache::Registry, например, активно использующие глобальные переменные, поскольку в этом случае сценарий каждый раз выгружается из памяти после исполнения (единственное преимущество по сравнению с CGI здесь в том, что не требуется обращаться к внешнему интерпретатору).

Иногда обработчик привязывается к расширению через MIME-тип, что довольно часто практикуют для подключения mod_php:

LoadModule php5_module /usr/lib/аpache2/modules/libphp5.so
<IfModule mod_php5.c> 
 AddType application/x-httpd-php .php .phtml .php3 
 AddType application/x-httpd-php-source .phps
</IfModule>

Подробности ищите в документации по конкретному модулю.

На этом мы завершим наш краткий экскурс в Apache. Возможностей у этого сервера, как видите, множество. Если вы желаете поглубже разобраться в них, то более подробное изучение можно начать с сайта http://httpd.аpache.org. Ну и Google тоже не зря столь активно использует открытые проекты...

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию