Частенько возникает ситуация, когда модуля mod_php для Apache не хватает — надо разрулить права или сделать управление процессами — приходится ставить CGI. А CGI — это достаточно медленно в сравнении с mod_php. На ум сразу приходит FastCGI, однако mod_fastcgi только для Apache 1.3 — по сути отмирающей ветки, да и глюков у него хватает. Далее кто-то уходит на lighttpd, кто-то ищет решения для Apache 2.x.
По сути решение есть. Это mod_fcgid — аналог mod_fastcgi, но для Apache 2.x. Сайтик тута: https://fastcgi.coremail.cn/
Принцип действия FastCGI в целом таков: вместо того, чтобы запускать по одному процессу на каждый запрос, запускается тот же процесс, но как процесс-сервер. Он обрабатывает запросы клиентов по очереди, не завершаясь между запросами. Если один процесс не успевает в разумное время обрабатывать запросы — запускается еще один. Если процесс бездействует — он завершается FastCGI-диспетчером. Это вкратце.
Обилие настроек по первости поражает — легко сделать ошибку. Вкратце опишу, как настроить mod_fcgid в пределах vhost’а. Нам потребуется PHP, скомпиленный с поддержкой FastCGI. Проверяется просто: php -v должно выдавать что-то вроде PHP 5.2.5 (cgi-fcgi) (built: Dec 19 2007 12:00:49) (ключевые буковки: cgi-fcgi).
Надеюсь, собрать из исходников mod_fcgid вам проблемы не составит. Если составит — ищем веточку по сборке софта (если ее еще нет — она появится). Считаю, что собрали.
—
Для начала сетапим Apache. Вполне сойдет worker_mpm, prefork не нужен. Нам потребуется добавить строчки:
LoadModule fcgid_module modules/mod_fcgid.so
(mod_fcgid.so не забываем прокинуть в каталог modules)
IdleTimeout 30
IdleScanInterval 30
BusyTimeout 600
BusyScanInterval 60
IPCConnectTimeout 10
IPCCommTimeout 120
SocketPath /tmp/fcgi
SharememPath /tmp/fcgi/fcgid_shm
MaxProcessCount 1024
DefaultMinClassProcessCount 0
DefaultMaxClassProcessCount 32
MaxRequestsPerProcess 200
PHP_Fix_Pathinfo_Enable 1
Здесь чуть-чуть поясню, ибо параметры придется подбирать по вкусу.
IdleTimeout — это время бездействия запущенного процесса перед тем, как он будет убит. IdleScanInterval — интервал сканирования процессов на бездействие. BusyTimeout — время занятости процесса одним запросом до убиения (если процесс занят больше указанного одним запросом — он будет убит, как зависший). BusyScanInterval — интервал сканирования на зависы. IPCConnectTimeout — время ожидания соединения с выбранным не занятым процессом. Если соединиться за указанное время не удалось — выбранный процесс убивается, как подвисший, а клиенту возвращается 500. IPCCommTimeout — время ожидания первой порции данных (ответа) от процесса. Если ответа нету — также KILL+500.
SocketPath и SharememPath — это служебные пути. Первый путь — к каталогу, в котором будут создаваться сокеты для связи с процессами FastCGI. Второй — к файлу разделяемой памяти диспетчера FastCGI, который будет создан во время работы. Каталог должен существовать.
MaxProcessCount, DefaultMinClassProcessCount, DefaultMaxClassProcessCount — это управление нагрузкой. Первое — максимальное число всех процессов на весь сервер (все виртуалхосты). Второе — минимум процессов для одного приложения (например — PHP), которое будет поддерживаться. Тут я ставлю 0 — т.е. если вхост вообще не активен, пусть лучше убьются все, и не занимают бестолку память. Третье — максимум процессов для одного приложения.
MaxRequestsPerProcess. Количество запросов, после которого процесс будет убит и перезапущен. Т.е. обработали 200 запросов — будьте добры в рестарт. Меньшее число повышает надежность, большее — производительность. PHP со значениями 500 и выше в стандартной конфигурации может и не работать.
PHP_Fix_Pathinfo_Enable — тут единичка, потому что работаем корректно — надо давать PHP нормальные скриптовые пути. Не забудьте в php.ini поставить cgi.fix_pathinfo = 1.
—
Теперь сетапим типовой vhost:
ServerAdmin mymail@mydomain
ServerName myhost.mydomain
CustomLog /www/myhost/logs/access_log common
ErrorLog /www/myhost/logs/error_log
SuexecUserGroup myuser mygroup
DocumentRoot /www/myhost/html
<Directory /www/myhost/html>
Allow from all
AllowOverride all
Options Includes SymLinksIfOwnerMatch ExecCGI
DirectoryIndex index.php index.htm index.html default.htm default.html
AddHandler fcgid-script .php
FCGIWrapper «/www/fastcgi/myhost/php.fcgi» .php
</Directory>
</VirtualHost>
Ключевые строчки здесь:
AddHandler fcgid-script .php
FCGIWrapper «/www/fastcgi/myhost/php.fcgi» .php
В первой обратите внимание на SymLinksIfOwnerMatch ExecCGI. Эти строчки нужны для выполнения PHP как CGI.
Во второй все просто — мы добавляем обработчик fcgid к файлам .php.
В третьей мы связываем обработчик с нашим конкретным приложением (будьте внимательны — на каждый вхост придется делать отдельное, во-первых из-за ограничений DefaultMin(Max)ProcessCount — они работают попроцессно, во-вторых из-за разграничения прав — файл php.fcgi должен быть создан с пользователем и группой, указанными в SuexecUserGroup.
Заметьте, что я выношу файлы php.fcgi за пределы дерева каталогов пользователя, чтобы он не мог получить доступ к этому файлу, например, с помощью того же PHP. Еще разумно в ext3 поставить этому файлу immutable-бит, чтобы уж точно никто его не изменил.
Теперь о файле php.fcgi. Файл php.fcgi представляет собой «враппер» для процесса PHP, на каждый vhost. Он дает нам возможность гибко манипулировать настройками каждого хоста. Пример файла:
export PHPRC=»/www/myhost/etc»
export PHP_FCGI_MAX_REQUESTS=500
export PHP_FCGI_CHILDREN=2
export TZ=»Europe/Moscow»
export LANG=»ru_RU.UTF-8″
export PWD=»/www/myhost/html»
exec /www/fastcgi/PHP/php -c /www/myhost/etc/php.ini
Тут все просто. Задаются переменные среды и запускается PHP с указанием на конфиг для данного вхоста. Отдельно обращу внимание на две вещи.
Первая — PHP_FCGI_CHILDREN. PHP — это несколько необычный FastCGI-сервер — он не просто запускается и принимает запросы, он еще и порождает дочерние процессы («потоки»), которые эти запросы обрабатывают — т.е. содержит в себе еще и собственный диспетчер процессов. Везде рекомендуется число 1, чтобы он не использовал встроенный диспетчер, однако я экспериментально для себя уяснил, что 2 слегка понижает время ответа сервера и позволяет mod_fcgid не плодить кучу процессов из-за миллисекундной занятости PHP.
Вторая вещь — переменная PWD. Такой финт ушами позволяет PHP считать, что он запущен в каталоге, указанном в значении переменной. Что самое веселое — cd, который также меняет PWD, создает OLD_PWD, который и воспринимает PHP — т.е. cd «сменить» PHP видимый каталог — не поможет. А посему и использован такой необычный подход.
—
Вуаля. Надеюсь это слегка поможет вам в правильной организации вашего хостинга.
Предлагаю делиться собственным опытом.
https://ff.net13.info/index.php?showtopic=23784
Просмотров: 3030