Що таке PHP-FPM і навіщо його налаштовувати
PHP-FPM (FastCGI Process Manager) — менеджер процесів PHP, який запускає PHP як окремий сервіс. У зв'язці з Nginx він забезпечує високу продуктивність: Nginx обробляє статику, а PHP-FPM — динамічні запити. Правильне налаштування PHP-FPM дозволяє обслуговувати у 2–5 разів більше запитів без збільшення RAM.
Файл конфігурації пулу
Основний файл пулу міститься в /etc/php/8.x/fpm/pool.d/www.conf. Відкрийте його для редагування:
sudo nano /etc/php/8.2/fpm/pool.d/www.confРежими керування процесами (pm)
Параметр pm визначає, як PHP-FPM керує дочірніми процесами:
| Режим | Опис | Коли використовувати |
|---|---|---|
static | Фіксована кількість процесів | Високонавантажені сервери з достатньою RAM |
dynamic | Кількість процесів змінюється динамічно | Більшість VPS (рекомендовано) |
ondemand | Процеси створюються на запит | Сервер із малим трафіком, економія RAM |
Оптимальні значення pm для dynamic
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8
pm.max_requests = 500ps -o rss= -C php-fpm8.2 | awk '{ sum+=$1 } END { print sum/NR/1024 " MB" }'Slow Log — аналіз повільних скриптів
Увімкніть slow log для діагностики вузьких місць:
slowlog = /var/log/php8.2-fpm-slow.log
request_slowlog_timeout = 5sПереглядайте лог командою: tail -f /var/log/php8.2-fpm-slow.log
Сторінка статусу PHP-FPM
Додайте до конфігу пулу:
pm.status_path = /statusУ Nginx додайте location:
location ~ ^/status$ {
allow 127.0.0.1;
deny all;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}Застосування налаштувань
sudo systemctl reload php8.2-fpm
sudo systemctl status php8.2-fpmreload, який застосовує конфіг без обриву активних з'єднань.Конфігурація Nginx для PHP-FPM
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_read_timeout 300;
}Реальні помилки PHP-FPM
Досягнуто pm.max_children
[27-Sep-2026 14:02:11] WARNING: [pool www] server reached pm.max_children setting (20), consider raising itУсі 20 воркерів пулу зайняті обробкою запитів, нові запити стають у чергу ядра ОС на сокеті. Якщо черга теж переповнюється, Nginx отримує відмову в з'єднанні та віддає клієнту 502 чи 504. Саме по собі попередження — не аварія, але часта його поява в логу означає, що pm.max_children занижений відносно реального трафіку, або скрипти стали виконуватися довше звичайного.
Воркер вбитий OOM killer'ом
Out of memory: Killed process 18432 (php-fpm) total-vm:512000kB, anon-rss:245000kB, file-rss:0kBЦей рядок — із системного журналу ядра (dmesg чи journalctl -k), не з логу PHP-FPM. Означає, що сумарна пам'ять усіх процесів перевищила фізичну RAM сервера, і ядро примусово завершило один із воркерів. Формула розрахунку pm.max_children без урахування пікового навантаження — прямий шлях до цієї помилки.
Між цими двома записами в логах є прямий зв'язок: якщо воркери регулярно впираються в pm.max_children, адміністратор у паніці піднімає ліміт без перерахунку доступної пам'яті — і отримує вже не чергу запитів, а падіння сервера цілком через нестачу RAM.
Коли типові значення pm не підходять
staticтримає фіксовану кількість процесів постійно — на сервері з рідкісним трафіком це чиста витрата RAM у простої.ondemandзаощаджує пам'ять, але додає затримку на форк нового процесу під час першого запиту після простою — для API з жорсткими SLA за часом відповіді це може бути неприйнятно.pm.max_children, розрахований лише за середнім розміром процесу, не враховує сплески: важкий звіт чи експорт може тимчасово роздути один воркер у рази — закладайте запас, а не працюйте впритул до ліміту RAM.
Перевірка результату
| Поле статусу | Про що каже |
|---|---|
| active processes | Скільки воркерів зайнято обробкою запиту прямо зараз |
| idle processes | Скільки воркерів простоює в очікуванні |
| listen queue | Запити, що очікують вільного воркера — в нормі 0 |
| max children reached | Скільки разів з моменту старту впиралися в pm.max_children |
curl "http://127.0.0.1/status?full"Ненульовий і зростаючий max children reached — сигнал підняти pm.max_children або спершу розібратися, чому запити стали виконуватися повільніше, перш ніж просто збільшувати ліміт.
Часті питання
Що станеться, якщо змінити pm.max_children на працюючому сервері через reload — чи обірвуться активні з'єднання?
Reload застосовує нову конфігурацію без обриву вже встановлених з'єднань — саме тому стаття радить використовувати його замість повного перезапуску під навантаженням. Нові значення pm.max_children та інших параметрів пулу починають діяти для нових запитів, а скрипти, що вже виконуються, встигають завершитися за попередніми правилами.
Чи потрібно змінювати max_requests, якщо сайт написаний на фреймворку з витоками пам'яті у скриптах?
Так, за витоків пам'яті у скриптах фреймворку кожен процес з часом накопичує все більше зайнятої пам'яті, тому параметр max_requests, який примусово перезапускає воркер після заданої кількості опрацьованих запитів, стає особливо важливим. Без нього витік поступово з'їдає RAM кожного процесу і наближає сервер до помилки нестачі пам'яті, описаної у статті.
Як зрозуміти, що поточних значень pm справді не вистачає, а сервер не просто тимчасово перевантажений іншим процесом?
Варто дивитися на поле listen queue і лічильник max children reached на сторінці статусу протягом тривалого періоду, а не одноразово: окремий спалах може пояснюватися сусіднім фоновим процесом, а стійке зростання саме цих показників каже про нестачу воркерів для реального трафіку. Корисно порівняти час спалахів із логами інших служб на тому самому сервері, перш ніж змінювати конфігурацію пулу.
Чи можна використовувати режим ondemand разом зі сторінкою статусу PHP-FPM?
Так, режим ondemand і сторінка статусу pm.status_path сумісні — статус показує поточний стан пулу незалежно від того, як створюються процеси: динамічно, статично чи на запит. Різниця лише в тому, що за ondemand лічильник idle processes у стані спокою зазвичай близький до нуля, оскільки процеси не тримаються запущеними без потреби.