Apache, mod_perl и mod_proxy
Статьи
Apache, mod_perl и mod_proxy
Немного истории
В конце 2005 года на одном сервере было уже довольно много сайтов. Причём, все они обслуживались одним экземпляром Apache (на MPM-модуле prefork). Среди этих сайтов были хорошо посещаемые, так что иногда сервер начинал «задыхаться» и тормозить. Нам это не нравилось, поскольку мы могли рассчитать, что через некоторое (и весьма короткое) время сервер просто «загнётся» от количества запросов.
Мы начали исследовать, как можно выйти из этой проблемы.
Были испробованы разные подходы, в т. ч. увеличение количества слушающих детей (дочерные процессы Apache, которые обслуживают клиентские запросы). Не помогало. Наоборот, при увеличении количества дочерних процессов, они съедали всю оперативную память.
Затем, мы посмотрели, на что же тратится ресурс Apache. Выяснилось, что таких областей ровно две: «простые» файлы (.html, .htm, .gif etc.) и скриптовые (в нашем случае, это .pl). На вторые приходилась львиная доля ресурсов сервера.
Тут же возникла идея их разделить. Т. е. сделать так, чтобы один экземпляр работал с простыми файлами, а второй со скриптами. Как выяснилось, сделать это можно с помощью mod_proxy.
В итоге получилась следующая схема (вкратце).
Запускаются два экземпляра Apache:
- Первый, максимально облегчённый, экземпляр обрабатывает только «лёгкие» (простые) файлы, все остальные переправляются второму.
- Второй, с подключенным mod_perl, занимается всеми скриптовыми делами и результаты отправляет первому.
Теперь подробнее.
Системный сервис httpd был клонирован и назван httpdp (HTTPd proxy). Также был клонирован и сам файл /usr/bin/httpd, и назван httpd_perl. Теперь httpdp запускал /usr/bin/httpd_perl.
Были разнесены конфиги для этих (теперь уже) разных Апачей, и в них сделаны такие изменения:
1. httpd слушает теперь только Интернет. В конфиге нет никаких и иже с ними. В конце добавлено (для всего сервера или отдельного VirtualHost):
RewriteEngine On
RewriteRule \.(html|htm|css|js|txt|gif|jpg|jpeg|png|ico)$ - [last]
RewriteRule \.(mp3|wmv|rar|zip|pdf|rtf|doc|xls)$ - [last]
RewriteRule ^/(.*)$ http://localhost:<нужный локальный порт>/$1 [proxy]
ProxyPassReverse /pcgi/ http://localhost:<нужный локальный порт>/pcgi/
2. httpdp слушает только локальные порты (localhost), по одному на каждый сайт. В нём расписаны и т. д. Также, к нему-то и подключён mod_perl:
Alias /pcgi/ /home/httpd/modperl/pcgi/
PerlOptions +Parent
PerlSwitches -I/home/httpd/modperl/pcgi
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
PerlOptions +ParseHeaders
Options +ExecCGI
Также для вышестоящей секции можно применить другую конфигурацию с использованием ModPerl:: RegistryPrefork.
В таком виде система и работает до сих пор. Расход памяти значительно меньше, скорость работы не меньше, чем при обычном использовании mod_perl.