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_servers, pm.min_spare_servers и pm.max_spare_servers. Максимальное количество запросов на процесс по умолчанию не ограничено, но хорошо бы установить какое-нибудь небольшое значение, например 200, и избежать проблем с памятью. Такого вида настройка может обрабатывать большое количество запросов, даже если значение параметра невелико.
В итоге, получаем примерно такой блок конфигурации:
Читайте также
Настройка и highload-тюнинг php-fpm Попробуем определить каким образом можно повысить производительность сервера приложений на базе php-fpm, а также сформировать чек-лист для проверки конфигурации fpm…
Cлучайные числа с плавающей точкой в PHP Стандартные библиотеки PHP умеют генерировать только целые случайные числа. Однако, возникают задачи где нужно не целое рандомное число с максимально…
Особенности http_build_query в PHP Казалось бы http_build_query — простая функция, однако, имеет некоторые особенности. Нельзя однозначно сказать что это баг, скорее просто недокументированная фича,…
Установка и настройка связки nginx и php-fpm
Nginx в силу своей архитектуры быстро обрабатывает запросы и отдает статичные данные, в результате чего проект завоевал свою нишу на рынке, вытеснив такого мамонта, как Apache HTTP Server. Наличие в nginx поддержки интерфейсов (CGI, FastCGI и т.п.) позволило использовать его в связке с внешними приложениями, например, PHP, Perl, Python и другими. Описываемый в статье механизм не является новым и используется на высоконагруженных серверах уже давно. Статья написана в качестве заметки для себя и опубликована лишь только с той целью, что материал может оказаться полезным другим.
Итак, nginx является HTTP-сервером, а также умеет проксировать протоколы TCP, UDP, IMAP, POP3, HTTP и другие. Насколько мне известно, при написании nginx были использованы принципы событийно-ориентированного программирования, что и позволило добиться быстрой и эффективной обработки запросов с минимальными затратами ресурсов.
Ранее применение nginx было оправдано прежде всего для статических веб-сайтов. Однако с популяризацией данного продукта во многих приложениях появились возможности для привязки nginx без дополнительных ухищрений. Так, в PHP с версии 5.3.3 включен менеджер процессов FastCGI (PHP-FPM), который управляет ресурсами, а также созданием и уничтожением процессов PHP. Таким образом, появилась возможность из коробки использовать nginx в связке с PHP без включения в цепочку Apache HTTP Server с mod_php. Из недостатков данной связки следует отметить отсутствие в nginx аналогичного .htaccess в Apache механизма, который поддерживается практическими всеми веб-приложениями и позволяет гибко переносить их конфигурацию. Из-за этого, настройка веб-сервера осуществляется только в конфигурационном файле nginx, а директивы, указанные в .htaccess, приходится переводить в указанный конфиг. Опять же, нет худа без добра, отказ от данного механизма положительно сказывается на производительности, в результате снижения количества запросов к носителю информации (в конце статьи есть ссылка на заметку с комментариями разработчиков по этому поводу).
В портах FreeBSD доступно три вариации nginx: lite, full и обычная, которые различаются набором компилируемых модулей. Я ставлю обычную версию со своим набором опций и из своего репозитория. Также устанавливаем PHP с включенной опцией FPM (в официальном репозитории пакетов она включена).
Далее, немного расскажу о иерархии директорий сайтов у меня на сервере. У каждого пользователя домашней директорией является /home/username/data с правами 0750, в которой есть следующие поддиректории: logs, www, tmp. В директории www хранятся сайты, logs логи виртуальных хостов, а в tmp временные файлы PHP. Чтобы nginx мог получить к этим директориям доступ нужно добавить пользователя www в группу пользователя или можно воспользоваться ACL,ками, как сделал я: