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 запрос — 1 процесс, mod_fcgid не умеет отправлять несколько паралельных запросов запущенному fastcgi процессу, в случае с PHP это и не требуется, так как для корректной работы данной связки параметр нужно использовать PHP_FCGI_CHILDREN=0.
  2. Низкая эффективность различного рода 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, планирую использовать такую связку.

Комментировать

Это не спам.