Если вы используете PHP-FPM на своём сервере, особенно при росте трафика, вы могли столкнуться с предупреждением: «WARNING: [pool www] seems busy (you may need to increase pm.start_servers, pm.min_spare_servers, pm.max_spare_servers, or pm.max_children)». Это предупреждение часто неправильно понимают. Я, как HostingServer.com.tr, решил написать эту статью, так как этот вопрос задают часто. Вместо простого увеличения max_children мы рассчитаем реальную потребность и найдём окончательное решение.
Почему возникает предупреждение?
PHP-FPM создаёт отдельный дочерний процесс для каждого запроса. pm.max_children определяет максимальное количество одновременно работающих процессов. Когда это значение достигается, новые запросы ставятся в очередь и обрабатываются по мере освобождения процессов. Если количество ожидающих запросов сильно возрастает, сервер замедляется и вы получаете ошибки. Настройки по умолчанию часто недостаточны. Например, на виртуальном сервере DigitalOcean с 2 ГБ ОЗУ значение max_children по умолчанию обычно составляет 5–10. Однако если у вас одновременно 30–40 посетителей, этого значения явно мало.
Точное решение: расчёт ресурсов
Чтобы найти правильное значение max_children, нужно знать, сколько ОЗУ потребляет каждый процесс PHP-FPM. Это можно узнать с помощью команды: ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%dMB", sum/1024) }'. Эта команда выводит общее использование ОЗУ всеми процессами PHP-FPM в МБ. Затем разделите на количество процессов, чтобы получить среднее потребление памяти. Например, если 10 процессов используют 512 МБ, то на каждый процесс приходится около 51 МБ. Не забывайте, что на сервере работают и другие службы. Оставьте запас и выделите PHP-FPM 80% от всей ОЗУ. 80% от 2 ГБ = 1,6 ГБ = 1638 МБ. 1638 / 51 ≈ 32. Значит, max_children = 32. Также настройте pm.max_spare_servers и pm.min_spare_servers соответственно. Рекомендую: min_spare = 5, max_spare = 15.
Альтернативный метод: измерение pm.status
Другой способ — открыть страницу pm.status и наблюдать за данными в реальном времени. Настройте pm.status_path = /status и используйте curl http://localhost/status?full, чтобы увидеть текущее количество процессов и очередь ожидания. Если «listen queue» постоянно больше 0, то max_children нужно увеличить. Но помните: простое увеличение не поможет, если на сервере началось использование swap — это значит, что ОЗУ недостаточно. Тогда либо добавляйте ОЗУ, либо оптимизируйте приложение.
Изменение настроек PHP-FPM
Чтобы изменить настройки, отредактируйте файл /etc/php/8.x/fpm/pool.d/www.conf. Значения по умолчанию: pm = dynamic, pm.max_children = 5, pm.start_servers = 2, pm.min_spare_servers = 1, pm.max_spare_servers = 3. Запишите свои рассчитанные значения и перезапустите службу: systemctl restart php8.2-fpm (версия может отличаться). Наблюдайте в течение дня; если предупреждение повторяется, повторите расчёт.
Что нужно помнить
- Каждый процесс использует разное количество памяти в зависимости от приложения. Сайт на WordPress может потреблять 30 МБ, а Magento — 100 МБ.
- Другие службы на сервере (MySQL, Nginx, Redis и т.д.) также занимают память. Учитывайте их.
- Избегайте использования swap; чрезмерное использование swap снижает производительность.
Важно: установка слишком высокого значения max_children может привести к краху сервера. Всегда увеличивайте его постепенно и с запасом.
Заключение
Предупреждение PHP-FPM max_children, если его игнорировать, ухудшает пользовательский опыт. Но решить его правильным методом не так сложно, как кажется. Измерьте ресурсы вашего сервера, рассчитайте реалистично и настройте параметры соответственно. На HostingServer.com.tr вы найдёте больше материалов по этой теме и можете задать вопросы в комментариях. В следующей статье я расскажу о мониторинге в реальном времени с помощью pm.status.