PHP-FPM. НАСТРОЙКА И ТЮНИНГ

php-fpm – PHP FastCGI менеджер процессов. Используется в связке с nginx + php. По моему мнению лучшая связка  для веб-сайтов.

Цель

Разобраться в параметрах конфигурации, и решить проблему, которая возникла на продакшен сервере с чрезмерным потреблением оперативной памяти. Произошло это потому, что php-fpm породил множество дочерних процессов, которые с радостью съели память, и, в один прекрасный момент, когда еще запустился парсер, OOM-killer положил мою машину. Причем ночью. На 6 часов. Почему она именно зашатдаунилась, а не ребутнулась – это другой вопрос, но неприятный впечатлений была масса.

Конфигурация и термины

/etc/php-fpm.conf – глобальная конфигурация

/etc/php-fpm.d/* – конфигурация пулов

Pool – это группа процессов, выделенная для обработки запросов, поступающих на определённый порт или Unix-сокет. В PHP-FPM возможно использовать отдельные пулы для каждого сайта и точно распределять ресурсы, а также использовать разных пользователей и разные группы для каждого пула.

Если пулы работают от имени одного и того же пользователя, разделение приложений по пулам позволяет предотвратить ситуацию, когда высоконагруженное приложение постоянно держит занятыми процессы-обработчики, не давая таким образом нормально работать лёгким интерактивным приложениям.

Для каждого из пулов можно задавать разные настройки PHP. Причем эти настройки будут иметь приоритет выше, чем те, что в php.ini либо те, которые могут задаваться напрямую из php-скриптов.

Конфигурация и параметры

Итак, начнем с глобального конфига:

Теперь можно рассмотреть конфигурацию пула (для примера /etc/pfp-fpm.d/blog.conf):

Также, отредактируем php.ini файл, указав:

О подсчетах параметров:

Остается закономерный вопрос: а как же выбрать комфортные параметры для сайта? С дефолтным конфигом сделаем следующее:
1. Предположим, что у нас есть VDS с 512 Mb оперативной памяти, из которой 200 Mb мы можем выделить под PHP-FPM.
2. Возьмем “тяжелые” страницы сайта и откроем их (желательно почти параллельно) в том колличестве, сколько потенциально их может быть открыто параллельно в пиковые нагрузки (при этом количество страниц возьмем с небольшой дельтой в большую сторону)
3. Смотрим через htop количество памяти, которое забрали под себя процессы php-fpm. Добустим это 20 Mb на каждый. Тогда добавив дельту в 10%, будем считать что это 22 Mb.
4. Считаем значение для параметра pm.max_children:
200 / 22 = 9.09

Приемлемым значением pm.max_children будет 9. Это значение основано на среднем значении и возможно далее его необходимо будет изменить, когда вы заметите длительное время использования памяти процессом. После быстрого тестирования несложно выбрать значения pm.start_serverspm.min_spare_servers и pm.max_spare_servers. Максимальное количество запросов на процесс по умолчанию не ограничено, но хорошо бы установить какое-нибудь небольшое значение, например 200, и избежать проблем с памятью. Такого вида настройка может обрабатывать большое количество запросов, даже если значение параметра невелико.

В итоге, получаем примерно такой блок конфигурации: