Apache2.2 + mod_fcgid + php
В некоторых проектах на текущий момент использую связку Apache 2.2 + mod_fastcgi + php. Запускаемый PHP при помощи suexec работает с правами пользователя, что дает возможность перенести вопросы связанные с безопасностью и изолированностью выполняемых скриптов на уровень ОС.
В последнее время в такой связке я разочаровался, mod_fastcgi не обеспечивает приемлемый уровень производительности и надежности для WEB проектов использующих язык PHP, в итоге решил протестировать связку Apache 2.2 + mod_fcgid + php.
Ограничения mod_fcgid:
- 1 запрос — 1 процесс, mod_fcgid не умеет отправлять несколько паралельных запросов запущенному fastcgi процессу, в случае с PHP это и не требуется, так как для корректной работы данной связки параметр нужно использовать PHP_FCGI_CHILDREN=0.
- Низкая эффективность различного рода opcode кешеров, так как каждый запущенный fastcgi не имеет доступ к разделяемой памяти других fastcgi процессов (это описано в документации по mod_fcgid, пока не тестировал)
Непосредственно настройка:
Считаем, что Apache 2.2 + suexec и PHP с поддержкой FastCGI у вас установлен, далее устанавливаем libapache2-mod-fcgid и изменяем стандартную конфигурацию:
cat /etc/apache2/mods-enabled/fcgid.conf
<IfModule mod_fcgid.c>
AddHandler fcgid-script .fcgi
FcgidConnectTimeout 20
FcgidBusyTimeout 60
FcgidBusyScanInterval 61
SocketPath /var/lib/apache2/fcgid/sock
FcgidMaxProcessesPerClass 100
FcgidMaxProcesses 400
FcgidPassHeader Authorization
FcgidPassHeader Proxy-Authorization
FcgidPassHeader HTTP_AUTHORIZATION
AddHandler php-fcgi .php
Action php-fcgi /php-fcgi/php.sh
Action application/x-httpd-fastphp /php-fcgi/php.sh
Action application/x-httpd-php /php-fcgi/php.sh
AddType application/x-httpd-fastphp .php
<Location /php-fcgi/>
Options ExecCGI FollowSymLinks
SetHandler fcgid-script
</Location>
</IfModule>И выполняем 2-е команды: a2enmod fcgid && /etc/init.d/apache2 restart
Пример конфигурационного файла для VirtualHost в Apache 2.2:
<VirtualHost *:80>
ServerName papyrus
ServerAdmin webmaster@localhost
DocumentRoot /var/www/papyrus/www/web
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/papyrus/www/web>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
Alias /php-fcgi/ /var/www/papyrus/cgi-bin/
SuexecUserGroup papyrus papyrus
Alias /sf /var/www/papyrus/symf/data/web/sf
<Directory "/var/www/papyrus/symf/data/web/sf">
AllowOverride All
Allow from All
</Directory>
<Directory "/var/www/papyrus/cgi-bin">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/papyrus-error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/papyrus-access.log combined
</VirtualHost>Данный конфигурационный файл используется для проекта написанного на Symfony, можете его отредактировать для своих нужд. Основные параметры:
/var/www/papyrus/cgi-bin/ — папка к которой находится файл php.sh, в случае запроса *.php скриптов именно этот скрипт служит как программа, которая вызывается для обработки таких запросов.
SuexecUserGroup — пользователь и группа с правами которого будут запускаться php скрипты, в данном случае это пользователь и группа papyrus, группа данного пользователя должна быть в группе www-data, иначе при выставленных правах 750 на папку /var/www/papyrus/ Apache не сможет прочитать статические файлы. Пример:
papyrus:x:1003:www-dataПример файла php.sh:
#!/bin/sh
PHP_FCGI_CHILDREN=0
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS
exec /usr/bin/php5-cgiПосле перезапуска Apache 2.2 и просмотра страницы http://papyrus/ у вас должен отработать PHP скрипт, в него можете поместить тотже phpinfo(). В случае проблем — смотрите логи, основной момент, про который обычно забывается — это права на папки и файлы, они должны быть аналогичные тем, который указаны в SuexecUserGroup.
По поводу скорости работы — на моем ноутбуке сопоставимо с mod_php, с учетом того, чт о в Apache использую MPM-Worker — все работает достаточно быстро и стабильно, через некоторое время проверю данную схему в какой-нибудь production среде, тогда дополню данную заметку.
Почему кстати используется PHP_FCGI_CHILDREN=0 — главный момент, это то, что PHP не управляет своими дочерними процессами, так как их нет, и в случае выпадения php5-cgi процесса в zombie, mod_fcgid должен будет корректно его перезапустить, кстати, аналогичную рекомендацию по настройке приводят и разработчики mod_fastcgi. Так что до тех пор, пока не будет доделан apache-like режим в php5-fpm, планирую использовать такую связку.




