Community
60
HostiServer
2026-06-04 15:11

Оптимізація PHP-сервера у 2026: PHP-FPM, OPcache, JIT та профілювання

⏱️ Час читання: ~11 хвилин | 📅 Оновлено: Червень 2026

Оптимізація PHP-сервера у 2026: PHP-FPM, OPcache, JIT та профілювання

PHP запустився у 1995 році як набір CGI-скриптів на Perl для відстеження відвідувачів сторінки. Через тридцять років він обслуговує близько 76% усього вебу (W3Techs, 2026) — від однієї людини, яка веде блог на WordPress, до Slack, Wikipedia і Etsy. Жодна інша мова не пройшла подібний шлях з настільки збереженою сумісністю: код, написаний у 2010-му, у переважній більшості випадків запуститься на PHP 8.4 без правок.

Те, що змінилось драматично — це спосіб запуску PHP на сервері. У 2010-му стандартом був mod_php в Apache: один процес Apache = один інтерпретатор PHP, повільно, споживливо до RAM, але просто. У 2026-му стандарт — PHP-FPM з окремим пулом воркерів, OPcache з прекомпільованим байткодом у пам'яті, JIT-компілятор, що генерує машинні інструкції для гарячих ділянок коду. Усе це разом дає продуктивність у 5-10 разів вищу за mod_php, але вимагає налаштування.

Проблема в тому, що apt пакети ставлять PHP з консервативними значеннями за замовчуванням — такими, щоб запустилось і на VPS з 512 МБ RAM, і на сервері з 64 ГБ. У результаті 90% серверів у Інтернеті працюють із конфігами, які ніяк не відповідають їхньому залізу. Це стаття про те, як виправити цю ситуацію — без академічної теорії, з конкретними числами і реальними прикладами для PHP 8.4 на Ubuntu 24.04 LTS.

ℹ️ Перетин з іншими нашими матеріалами: базове встановлення PHP, Nginx і Apache детально розкрите у статті «Як розмістити PHP-сайт». Тонкощі тюнингу під високе навантаження (CPU vs ядра, NVMe vs SATA, мікро-кешування FastCGI) — у статті «Серверна конфігурація для високонавантажених сайтів». Тут — те, що йде між ними: фактичний тюнинг FPM, OPcache, JIT, профілювання, специфічна для PHP безпека.

Перший крок: знайти, що саме треба правити

Перед будь-якою оптимізацією треба точно знати, які саме файли конфігурації PHP читає на вашому сервері. На Ubuntu їх може бути кілька версій паралельно (PHP 8.1, 8.2, 8.3, 8.4 — все ставиться поряд), і часто-густо ваші зміни летять не туди, куди треба.

Команди, які дають точну відповідь

php -r 'echo php_ini_loaded_file() . PHP_EOL;'
# Виводить шлях до основного php.ini для CLI

php-fpm8.4 -i | grep "Loaded Configuration"
# Шлях до php.ini для FPM (часто це /etc/php/8.4/fpm/php.ini)

php -r 'echo phpversion() . PHP_EOL;'
# Версія PHP, з якою працює CLI

systemctl status php8.4-fpm
# Чи запущений FPM-сервіс і який саме

⚠️ Часта пастка: налаштування для CLI (/etc/php/8.4/cli/php.ini) і FPM (/etc/php/8.4/fpm/php.ini) — це різні файли. Якщо ви правите CLI-конфіг, а ваш сайт працює через FPM, зміни не застосуються. phpinfo() у браузері покаже саме той php.ini, який обслуговує веб.

Структура каталогів PHP на Ubuntu

Шлях Що там лежить
/etc/php/8.4/fpm/php.ini Головний конфіг для веб-запитів (FPM)
/etc/php/8.4/cli/php.ini Конфіг для CLI (composer, artisan, wp-cli)
/etc/php/8.4/fpm/pool.d/www.conf Конфіг FPM-пулу — найважливіший файл для тюнингу
/etc/php/8.4/mods-available/ Конфіги розширень (opcache.ini, redis.ini, тощо)
/var/log/php8.4-fpm.log Логи FPM (slow log, помилки запуску воркерів)

Якщо у вас інша версія PHP — підставте її номер замість 8.4. На старіших Ubuntu (18.04, 20.04) шляхи можуть починатися з /etc/php5 або /etc/php/7.x.

PHP-FPM Pool: ключ до тримання навантаження

FPM-пул — це те, скільки одночасних PHP-процесів сервер може обслуговувати. Якщо налаштовано неправильно, сайт буде або «падати» від нестачі воркерів, або «вбивати» сервер через нестачу RAM. Це найважливіший конфіг для перформансу, і саме тут роблять найбільше помилок.

Три режими роботи: dynamic / static / ondemand

Режим Як працює Для кого
dynamic FPM тримає N воркерів готових, створює нові за потребою до max, прибирає неактивні Більшість сайтів — баланс RAM і чуйності системи
static FPM тримає рівно pm.max_children воркерів увесь час Високонавантажені сайти зі стабільним трафіком, де економія RAM не критична
ondemand Воркери створюються тільки коли є запит, помирають після таймауту Низькотрафічні сайти на VPS з малою RAM

Як розрахувати pm.max_children

Це число, яке найбільше впливає на стабільність. Формула:

pm.max_children = (Total RAM − RAM зайнята системою) / Середня RAM на один PHP-процес

На практиці один PHP-процес з WordPress і середнім набором плагінів їсть 50-80 МБ RAM під час обробки запиту. Для Laravel-додатків — 80-120 МБ. Magento 2 — 200-300 МБ. Заміряти точно можна командою:

ps -ylC php-fpm8.4 --sort:rss | awk '{sum+=$8; count++} END {print "Average:", sum/count/1024, "MB"}'

⚠️ Завжди залишайте безпечний буфер — 10-15% від отриманого числа pm.max_children на випадок різкого сплеску споживання пам'яті окремими воркерами. Якщо за формулою вийшло 25, виставляйте 20-22. Інакше при піковому трафіку всі воркери одночасно поглинуть залишок RAM, і Linux OOM-killer почне вбивати процеси — інколи саме MySQL або Nginx, бо вони можуть мати вищі OOM-scores.

Приклад розрахунку для типових серверів

Сервер Доступно для PHP RAM на процес pm.max_children
VPS 2 GB RAM, WordPress 1.2 GB (бо MySQL+Nginx їдять ~800 MB) 60 MB 17 (формула дає 20, мінус 15% буфер)
VPS 4 GB RAM, WooCommerce 2.5 GB 100 MB 22 (формула дає 25, мінус буфер)
VPS 8 GB RAM, Laravel API 5.5 GB 100 MB 48 (формула дає 55, мінус буфер)
Dedicated 32 GB, Magento 2 24 GB (велика частина на Redis і MySQL) 250 MB 82 (формула дає 96, мінус буфер)

Оптимальний конфіг пулу для dynamic-режиму

Файл /etc/php/8.4/fpm/pool.d/www.conf:

; Базові налаштування пулу
pm = dynamic
pm.max_children = 25
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8
pm.max_requests = 500

; Slow log — записує запити повільніші за 5 секунд
slowlog = /var/log/php8.4-fpm-slow.log
request_slowlog_timeout = 5s

; Status page для моніторингу — дивіться з 127.0.0.1
pm.status_path = /fpm-status
ping.path = /fpm-ping

ℹ️ Що робить кожен параметр:

  • pm.start_servers — скільки воркерів запустити при старті FPM
  • pm.min_spare_servers — мінімум вільних (готових прийняти запит) воркерів
  • pm.max_spare_servers — максимум вільних воркерів (понад це — починає вбивати зайвих)
  • pm.max_requests = 500 — воркер обслуговує 500 запитів і перезавантажується. Запобігає витокам пам'яті у плагінах третіх сторін

Slow log — недооцінений інструмент

Налаштування request_slowlog_timeout змушує FPM записувати у лог трасу будь-якого запиту, який виконується довше зазначеного часу. Це дозволяє знаходити «вузькі місця» без встановлення складних профайлерів. Приклад того, що з'являється у slow log:

[03-Jun-2026 14:23:15] [pool www] pid 12453
script_filename = /var/www/site/wp-cron.php
[0x00007f5e2c4a8e30] curl_exec() /var/www/site/wp-includes/class-wp-http-curl.php:155
[0x00007f5e2c4a8e30] request() /var/www/site/wp-includes/class-wp-http.php:413

Тут одразу видно: запит висить на curl_exec() у wp-cron — найімовірніше, плагін намагається достукатися до зовнішнього API, який не відповідає. Без slow log ця проблема залишилася б невидимою.

OPcache: каже одне число, що змінює все

OPcache — це вбудований у PHP байткод-кеш. Без нього PHP при кожному запиті заново читає всі .php-файли з диску, парсить їх у байткод і тільки потім виконує. З увімкненим OPcache байткод зберігається в RAM, і повторні виклики того ж файлу читають уже скомпільовану версію.

Це дає прискорення у 3-5 разів для будь-якого PHP-додатку без зміни жодного рядка коду. Це не теоретична цифра — це реальна різниця, яку видно на будь-якому профайлері.

Перевірити, чи OPcache увімкнений

php -r 'echo opcache_get_status() ? "OPcache: ON" : "OPcache: OFF"; echo PHP_EOL;'

Якщо OFF — увімкніть. На Ubuntu пакет називається php8.4-opcache (зазвичай уже встановлений за замовчуванням, але вимкнений у конфізі).

Робочий конфіг OPcache для продакшну

Файл /etc/php/8.4/mods-available/opcache.ini:

opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.revalidate_freq=2
opcache.validate_timestamps=1
opcache.save_comments=1
opcache.fast_shutdown=1
opcache.jit=tracing
opcache.jit_buffer_size=128M

Що означає кожен параметр

Параметр Що робить і як обрати значення
memory_consumption=256 Скільки RAM віддати кешу. 128 МБ вистачає для маленького WordPress, 256 МБ — для звичайного бізнес-сайту, 512 МБ — для Magento або великого Laravel. Якщо мало — у логах буде «opcache.max_accelerated_files reached»
interned_strings_buffer=16 Окремий буфер для кешу повторюваних рядків. 16 МБ — норма для більшості сайтів
max_accelerated_files=20000 Скільки файлів кешувати. Перевірте у моніторингу — якщо досягається ліміт, збільшуйте. WordPress з 30 плагінами легко набирає 8-12 тисяч файлів
validate_timestamps=1 Чи перевіряти, чи файл змінився на диску. 1 — перевіряти, 0 — НЕ перевіряти
revalidate_freq=2 Як часто перевіряти зміни файлів (у секундах). При validate_timestamps=0 цей параметр ігнорується

Важливий нюанс: validate_timestamps=0 для продакшну

Це найбільш суперечливий параметр. Якщо встановити validate_timestamps=0, PHP перестає перевіряти зміни файлів — і будь-яке оновлення коду треба супроводжувати ручним очищенням OPcache (php8.4-fpm reload або opcache_reset()). Натомість продуктивність зростає ще на 5-10%, бо нема системних викликів stat() при кожному запиті.

Чи варто? Залежить від процесу деплою. Якщо у вас CI/CD pipeline з автоматичним перезавантаженням FPM після релізу — точно так. Якщо ви оновлюєте сайт через FTP вручну і забуваєте перезавантажити сервіс — краще залишити validate_timestamps=1.

⚠️ Парадокс OPcache: після оновлення PHP-коду на диску, OPcache не побачить зміни до перезапуску FPM, якщо validate_timestamps=0. Це регулярно ламає WordPress-сайти у тих, хто читав статтю «як прискорити PHP», скопіював налаштування з продакшну і не зрозумів, що було за ними.

JIT compiler: коли вмикати, а коли — НІ

JIT (Just-In-Time compiler) з'явився у PHP 8.0 і дозволяє компілювати «гарячий» код у машинні інструкції процесора, обходячи інтерпретатор. Звучить як магія прискорення, але на практиці все цікавіше.

Де JIT реально допомагає

  • CPU-bound обчислення: рендеринг зображень, криптографія, парсинг великих структур даних, математичні алгоритми. Тут JIT може дати прискорення у 1.5-3 рази.
  • CLI-скрипти: довгі обробки даних, фонові обчислення, наукові розрахунки.

Де JIT не допомагає, а інколи шкодить

  • Типові веб-додатки (WordPress, Drupal, Laravel): вони I/O-bound (більшість часу проводять у запитах до БД, читанні файлів, очікуванні відповідей API). Прискорення від JIT — у межах 1-3%, що часто непомітно на тлі звичайної дисперсії.
  • Сайти з помилками сегментації: JIT у деяких випадках конфліктує зі сторонніми розширеннями. Якщо у логах з'явилися крахи воркерів після увімкнення — це перша гіпотеза.

Налаштування JIT

JIT керується через два параметри в opcache.ini:

opcache.jit=tracing
opcache.jit_buffer_size=128M
Значення opcache.jit Що означає
tracing Найагресивніший режим, компілює «гарячі» цикли і функції. Найкраща продуктивність
function Компілює окремі функції. М'якший режим, менше ризику
disable або 0 JIT вимкнений

Рекомендація: увімкніть tracing, заміряйте продуктивність до і після, тримайте увімкненим тільки якщо різниця помітна. На сайті з типовим CMS-навантаженням JIT може просто з'їсти 128 МБ RAM і нічого не дати в обмін.

Як заміряти ефект від JIT

Найпростіший спосіб — два інструменти разом: Apache Bench для навантажувального тесту і моніторинг через top:

# Тест без JIT (попередньо вимкніть JIT і перезавантажте FPM)
ab -n 1000 -c 10 https://yoursite.com/

# Тест з JIT (увімкніть, перезавантажте FPM)
ab -n 1000 -c 10 https://yoursite.com/

# Порівняйте "Requests per second" і "Time per request"

Якщо різниця менше 5% — JIT для вашого випадку економічно безглуздий, можна вимкнути і повернути 128 МБ RAM у систему.

Realpath cache: маленький параметр, який рятує SSD

Параметр, про який рідко говорять, але який має непропорційно великий ефект на сайтах з великою кількістю файлів (WordPress з 50+ плагінами, Magento, великі Laravel-проєкти).

Кожного разу, коли PHP підключає файл через require або include, він резолвить шлях через серію stat() системних викликів. Для відносного шляху типу ../vendor/symfony/finder/Finder.php це означає декілька десятків викликів до файлової системи. Realpath cache зберігає вже розв'язані шляхи в пам'яті.

Налаштування realpath_cache

У php.ini:

realpath_cache_size = 4096K
realpath_cache_ttl = 600

За замовчуванням стоїть 256K — цього вистачає на ~150 кешованих шляхів. Для WordPress з пристойним набором плагінів треба мінімум 2-4 MB. Перевірити поточне використання:

php -r 'echo realpath_cache_size() / 1024 . " KB used\n";'
# Скільки байтів реально займає кеш на даний момент

php -r 'print_r(realpath_cache_get());'
# Повний список усіх кешованих шляхів (корисно для діагностики)

Якщо число з першої команди близьке до значення realpath_cache_size у php.ini — кеш переповнюється, треба збільшувати ліміт.

💡 З досвіду: на WordPress-сайті з 40 плагінами і WooCommerce збільшення realpath_cache з 256K до 4M зменшує час генерації сторінки приблизно на 15-20% за рахунок самого тільки кешу шляхів. Прихована перемога, яку часто пропускають у гонитві за OPcache і Redis.

Профілювання: знайти, що насправді гальмує

До цього моменту ми тюнили «вгадуючи»: збільшили OPcache, збільшили pool, увімкнули JIT. Але справжня оптимізація починається тоді, коли ви бачите, де саме код проводить час. Без профілювання ви тюните не свій сайт, а абстрактного «середнього сайт».

Інструменти за зростанням складності

Інструмент Для чого Складність
FPM slow log Знайти запити-«тормози» без додаткових інструментів Низька
OPcache GUI (opcache-gui) Подивитись, як саме використовується OPcache, статистика hit ratio Низька
Xdebug profiler Детальне профілювання з cachegrind-форматом, відкривається у KCachegrind Середня
Blackfire / Tideways Production-ready APM, працює з мінімальним оверхедом Висока (комерційні)
strace / perf Системний рівень — що саме PHP робить на рівні OS Висока

З чого почати: OPcache GUI

OPcache GUI — це маленький .php-скрипт, який показує детальну статистику використання кешу. Встановлюється за хвилину:

cd /var/www/site/
wget https://raw.githubusercontent.com/amnuts/opcache-gui/master/index.php -O opcache-status.php

Після цього відкрийте у браузері https://yoursite.com/opcache-status.php — побачите memory usage, hit ratio, кількість кешованих файлів і список того, що в кеші. Якщо hit ratio менше 99% — це сигнал, що memory_consumption замалий.

🚨 Не залишайте opcache-status.php у відкритому доступі. Він показує внутрішню структуру файлової системи, версію PHP і список усіх плагінів — інформація, яка значно полегшує життя атакуючому. Або захистіть його nginx-правилом allow/deny з вашого офісного IP, або видаліть після перевірки.

Xdebug profiler — тонке профілювання

Xdebug — це найвідоміший дебагер і профайлер для PHP. Для профілювання його використовують у режимі profile:

; У /etc/php/8.4/mods-available/xdebug.ini
xdebug.mode = profile
xdebug.output_dir = /tmp/xdebug
xdebug.start_with_request = trigger

Після цього додайте параметр ?XDEBUG_TRIGGER=1 до URL — і Xdebug запише профіль виклику у каталог /tmp/xdebug. Відкрийте отриманий cachegrind.out файл у KCachegrind або QCachegrind — побачите ієрархію викликів з часом, відсотками і кількістю викликів.

⚠️ Не залишайте Xdebug в режимі profile на продакшні постійно. Він додає 20-100% оверхеду до часу виконання. Використовуйте тільки на час діагностики, потім вимкніть або переключіть на xdebug.mode = off.

PHP-специфічна безпека: те, що не покривають інші статті

Загальна безпека сервера (HTTPS, fail2ban, security headers) детально розкрита у нашій статті про захист сайту від хакерів. Тут — суто PHP-рівень: параметри, які можна виставити в php.ini і які закривають специфічні для PHP вектори атаки.

expose_php = Off

За замовчуванням PHP додає заголовок X-Powered-By: PHP/8.4.X до кожної відповіді. Це безкоштовна інформація для атакуючого: він точно знає вашу версію і може шукати CVE під неї. Вимкнути просто:

expose_php = Off

Перевірити після перезапуску FPM:

curl -I https://yoursite.com/ | grep -i powered
# Якщо нічого не виводить — заголовок прибраний

disable_functions: що дійсно варто вимикати

Це список PHP-функцій, які ніколи не виконуватимуться. Якщо плагін або вразливість намагається через них вирватися на рівень shell — PHP просто видасть помилку. Розумний мінімум для більшості сайтів:

disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_multi_exec,parse_ini_file,show_source,phpinfo

⚠️ Підводний камінь: деякі CMS і плагіни легально використовують ці функції. WordPress може використовувати proc_open для оновлень. Magento використовує shell_exec у деяких сценаріях. Перед застосуванням — перевірте на staging-копії. Якщо щось ламається, прибирайте функції зі списку по черзі, поки не знайдете винуватця.

open_basedir: ізоляція PHP від файлової системи

Цей параметр обмежує, до яких каталогів PHP-скрипт може звертатися. Навіть якщо зловмисник завантажив shell у /uploads, він не зможе через нього прочитати /etc/passwd або /var/log:

open_basedir = /var/www/yoursite/:/tmp/

Усе поза цими каталогами стає недоступним для функцій типу file_get_contents, fopen, include. Це один з найсильніших захистів на рівні PHP, але часто пропускається.

allow_url_fopen = Off (де можливо)

За замовчуванням PHP дозволяє відкривати URL так само як файли: file_get_contents('https://...'). Зловмисник може цим скористатися для:

  • SSRF (Server-Side Request Forgery) — змусити сервер ходити по внутрішніх ресурсах
  • Remote File Inclusion — підключити шкідливий PHP-код з зовнішнього сервера

Якщо ваш код не звертається до зовнішніх URL через file_get_contents (а замість цього використовує cURL або Guzzle, як прийнято у сучасних додатках) — вимкніть:

allow_url_fopen = Off
allow_url_include = Off

allow_url_include треба вимикати завжди — це окремий вектор для Remote File Inclusion і у 99% випадків нікому не потрібен.

session.cookie_httponly, session.cookie_secure

Налаштування PHP-сесій. Без них JavaScript на сторінці може прочитати session cookie (наприклад, через XSS-вразливість), або session cookie буде передаватися по HTTP в обхід HTTPS:

session.cookie_httponly = 1
session.cookie_secure = 1
session.cookie_samesite = "Strict"
session.use_strict_mode = 1

Топ помилок конфігурації, які я бачу на чужих серверах

  1. memory_limit = -1 «на всякий випадок». Це означає «без обмежень». Один зациклений скрипт може з'їсти всю RAM сервера. Має стояти конкретне число: 256M, 512M, 1024M.
  2. max_execution_time = 0. Те саме що вище — скрипт без таймауту може висіти годинами, тримаючи воркер FPM. 60-90 секунд — нормальний діапазон для більшості сайтів.
  3. display_errors = On у продакшні. Помилки виводяться користувачам у браузер разом зі шляхами до файлів, версіями бібліотек і інколи фрагментами SQL. Видавайте їх тільки на dev-сервері. У продакшн — display_errors = Off, log_errors = On.
  4. pm.max_children обраний наосліп. Або поставили 5 і сайт «падає» при першому ж сплеску трафіку, або поставили 200 і сервер захлинається. Розрахуйте формулою з секції про FPM.
  5. OPcache з memory_consumption=64. Стандартне значення з більшості туторіалів. Для будь-якого реального сайту з CMS це замало, кеш постійно переповнюється і скидається. Мінімум 128, реалістично 256-512.
  6. opcache.validate_timestamps=0 без CI/CD. Після деплою сайт показує стару версію коду, а адміни в розпачі шукають баги. Або ставте 1, або налаштовуйте автоматичний reload FPM після релізу.
  7. JIT з buffer_size=512M, бо «більше = краще». На сайті з CMS це з'їдає півгігабайта RAM ні за що. JIT використовує тільки те, що йому реально треба — починайте з 64-128M.
  8. info.php / phpinfo.php залишився у production. Тимчасовий файл, який створили для перевірки, але забули видалити. Атакуючий бачить версію PHP, всі завантажені модулі, шляхи, переменні середовища. Видаляйте відразу після перевірки — детальніше про небезпеку розкриття версій ПЗ і способи приховати їх ми писали у матеріалі про перевірку версії Apache.

🚀 PHP-сервер з правильним налаштуванням «з коробки»

Налаштування FPM, OPcache, JIT і профілювання — це не складно, але вимагає часу і досвіду. На Hostiserver більшість цих речей уже налаштовано за замовчуванням, а решту допомагає поставити техпідтримка під ваш конкретний проєкт і навантаження.

💻 Cloud (VPS) Хостинг

  • Від $19.95/міс — KVM-ізоляція, повний root-доступ
  • PHP 8.4 і 8.5 з оптимізованим php.ini для CMS і фреймворків з коробки
  • OPcache і JIT увімкнені та налаштовані під ваш профіль навантаження
  • PHP-FPM pool tuning — допомога з розрахунком pm.max_children під вашу RAM і CMS
  • Slow log і моніторинг — інженери допоможуть знайти вузькі місця у вашому коді
  • 24/7 інженерна підтримка — <10 хв відповідь, реальні DevOps-інженери

🖥️ Виділені Сервери

  • Від $90/міс — повна ізоляція, ресурси тільки для вашого проєкту
  • Тюнинг під високе навантаження — Magento, WooCommerce, великі Laravel-проєкти
  • Безкоштовна міграція з іншого провайдера з перевіркою конфігурації
  • Профілювання і аудит вашого PHP-стеку при онбордингу
  • SLA 99.9% uptime з гарантією у договорі

💬 Не впевнені, який варіант вам необхідний?
💬 Напишіть нам і ми зі всім допоможемо!

Часті питання

На яку версію PHP оновлюватися у 2026 році?

Мінімальна підтримувана версія — PHP 8.3 (підтримка завершується наприкінці 2026). Оптимальна для більшості проєктів — PHP 8.4, як стабільна, з активним security-супроводом. PHP 8.5 — поточна актуальна версія для тих, хто стежить за релізами і хоче нові фічі мови (property hooks, asymmetric visibility). До кінця року очікується реліз PHP 8.6. Все, що нижче PHP 8.2, не отримує security-патчів і несе ризики.

Чи варто переходити з mysqli на PDO?

Обидва розширення підтримуються і не deprecated. PDO дає переваги, якщо вам важлива портабельність між БД (MySQL, PostgreSQL, SQLite одним кодом) або зручність prepared statements у named-параметрах. mysqli залишається швидшим на 5-10% для чистих MySQL-запитів і має деякі MySQL-специфічні фічі (наприклад, multi-query, async queries). Для нового коду рекомендую PDO; для існуючого — не варто переписувати тільки заради переходу. Окремо про захист БД на серверному рівні і налаштування користувачів — у нашій статті про безпеку MySQL на хостингу.

Що пріоритетніше: OPcache чи Redis для кешування?

Це різні рівні кешу. OPcache кешує скомпільований байткод — без нього PHP читає і парсить .php файли при кожному запиті. Redis кешує дані додатку — результати SQL-запитів, рендеринг шаблонів, об'єкти. OPcache має бути увімкнений завжди — це базова річ. Redis додається після OPcache, коли вже бачите, що вузьке місце — це БД-запити. Не «один замість іншого», а «обидва послідовно».

Як зрозуміти, що сервер тримає поточне навантаження, чи треба апгрейдити?

Кілька маркерів. У логах FPM з'являється «WARNING: server reached pm.max_children setting» — пул переповнений, треба або апгрейдити RAM і збільшувати max_children, або шукати, чому запити такі повільні. У top показник Load Average наближається до кількості ядер або перевищує її — сервер працює на межі. Slow log регулярно записує запити >5 секунд — є код, який треба профілювати. opcache_get_status() показує hit_ratio менше 99% — OPcache замалий. Якщо все це лікується тюнингом, апгрейд не потрібен. Якщо параметри вже на стелі — час до більшого тарифу; вибір між VPS, виділеним і керованим сервером ми розбирали у окремому матеріалі про вибір типу сервера.

Чи потрібно щось окремо налаштовувати для Laravel або Symfony?

Базовий PHP-стек однаковий. Специфіка для фреймворків зводиться до чотирьох речей. По-перше, OPcache preloading (PHP 7.4+) — для Laravel і Symfony дає помітне прискорення, бо фреймворкове ядро завантажується у пам'ять один раз при старті FPM. По-друге, кеш конфігурації самого фреймворка: artisan config:cache, artisan route:cache, artisan view:cache для Laravel; console cache:warmup --env=prod для Symfony. По-третє, переконайтеся, що APP_DEBUG=false у продакшні — інакше всі помилки показуються клієнтам, а сам debug-режим серйозно сповільнює роботу. По-четверте, memory_limit для CLI має бути вищим, ніж для FPM — консольні команди (міграції, черги, генерація профілів, експорт даних) часто потребують 512M-1G, тоді як веб-запитам вистачає 256M.

Чому після оновлення коду сайт показує стару версію?

Майже завжди — це OPcache з validate_timestamps=0 або великим revalidate_freq. PHP кешує скомпільований байткод і не помічає, що файли на диску змінилися. Рішення: sudo systemctl reload php8.4-fpm після кожного релізу, або викликати opcache_reset() з PHP-скрипта (можна зробити hook у CI/CD), або встановити validate_timestamps=1 з малим revalidate_freq (наприклад, 2 секунди — мінімальний штраф продуктивності і автоматичне підхоплення змін).

Чи безпечно вмикати JIT на бойовому сервері?

Майже завжди так, але з застереженнями. JIT у PHP 8.4 уже стабільний і використовується у продакшні великими компаніями. Але є ситуації, де його краще не вмикати: якщо у вас сторонні бінарні розширення (особливо самописні), які не тестувалися з JIT; якщо у логах після увімкнення з'являються segfault'и воркерів; якщо ви бачите, що ваш сайт I/O-bound (більшість часу у запитах до БД) — JIT просто з'їсть RAM без віддачі. Стандартна порада: увімкніть на staging, навантажувальний тест, моніторинг — якщо все добре протягом тижня, виносіть на продакшн.

Contents

Поділіться цією статтею

VPS з підтримкою від

$19 95 / міс

Виділені сервери від

$80 / міс

CDN починаючи від

$0 / міс

 

Користуючись цим сайтом, ви погоджуєтеся на використання файлів cookies відповідно до нашої Політики Конфіденційності.