Продуктивність хостингу Технічні

OPcache, APCu та інші три букви, які прискорять PHP на хостингу вдвічі - без жодної зміни в коді

Серверна кімната кібербезпеки для оптимізації продуктивності php хостингу

Уявіть, що ваш сайт - це кухар у ресторані. Кожного разу, коли приходить замовлення на борщ, він не дістає готовий рецепт з полиці, а біжить до бібліотеки, знаходить книгу, перекладає рецепт з латини, а потім починає готувати. Абсурд? Саме так працює PHP без правильно налаштованого кешу опкодів. Щоразу один і той самий скрипт перекомпілюється заново, витрачаючи процесорний час на роботу, результат якої вже давно відомий. І поки ви шукаєте причину повільності у хостинг-провайдера, відповідь лежить буквально в одному конфігураційному файлі.

Що таке OPcache і чому ваш PHP без нього ледве дихає

PHP - інтерпретована мова. Це означає, що при кожному запиті сервер бере ваш .php-файл, розбирає його на токени, будує абстрактне синтаксичне дерево, компілює в байткод (опкод) і тільки потім виконує. OPcache зберігає вже скомпільований байткод у оперативній пам'яті, тож при наступному запиті вся ця робота просто пропускається.

Результат? За даними бенчмарків Zend, увімкнення OPcache прискорює виконання PHP-скриптів на 50-300% залежно від складності додатку. WordPress, наприклад, стабільно показує приріст у 2-3 рази на сторінках з великою кількістю плагінів.

Найцікавіше - OPcache вбудований у PHP починаючи з версії 5.5 (2013 рік). Він вже є на вашому сервері. Але на багатьох shared-хостингах він або вимкнений, або працює з дефолтними налаштуваннями, які підходять приблизно так само, як стандартний розмір взуття підходить усім.

Розробник налаштовує opcache та кеш php сервера на ноутбуці
Розробник налаштовує opcache та кеш php сервера на ноутбуці

APCu - кеш даних, про який забувають навіть досвідчені розробники

Якщо OPcache кешує скомпільований код, то APCu кешує дані - результати запитів, обчислень, будь-які PHP-змінні між запитами. Це як блокнот, куди кухар записує: "Борщ на 4 порції = 2 буряки, 3 картоплі, 1 морква". Наступного разу він просто дивиться в блокнот.

Типовий приклад: ваш інтернет-магазин при кожному завантаженні головної сторінки робить 15-20 SQL-запитів, щоб зібрати категорії, популярні товари, банери. APCu дозволяє зберегти ці результати на 60 секунд і віддавати їх з пам'яті, а не мучити базу даних знову і знову.

"Найшвидший запит до бази даних - це запит, який ніколи не був виконаний." - Барон Шварц, автор книги "High Performance MySQL"

Але є нюанс. APCu працює тільки в межах одного сервера. Якщо у вас кластер з кількох нод - APCu на кожній буде ізольованим. Для розподілених систем краще дивитися в бік Redis або Memcached. Проте для типового VPS чи навіть shared-хостингу APCu - це безкоштовна перемога.

Три інші "три букви": JIT, Redis, FPM

OPcache та APCu - це тільки початок. Є ще кілька скорочень, які безпосередньо впливають на продуктивність PHP на вашому хостингу.

  1. JIT (Just-In-Time компілятор) - з'явився у PHP 8.0 і перетворює байткод у машинний код процесора. Для CPU-інтенсивних задач (обробка зображень, математичні обчислення) дає приріст до 30-50%. Для типового WordPress ефект скромніший - 5-10%, бо там основне "вузьке горло" це база даних і введення-виведення.
  2. Redis - зовнішній кеш-сервер, що живе як окремий процес. На відміну від APCu працює між кількома серверами, підтримує складні структури даних (списки, множини, хеші). Ідеальний для сесій, черг і кешу сторінок.
  3. PHP-FPM (FastCGI Process Manager) - менеджер процесів PHP, який вирішує, скільки "воркерів" обробляють запити одночасно. Неправильно налаштований FPM - це як ресторан з одним офіціантом на 200 столиків.
Швидкість завантаження після php-fpm оптимізації WordPress на хостингу
Швидкість завантаження після php-fpm оптимізації WordPress на хостингу

Конкретні цифри: до і після налаштування

Теорія - це чудово, але давайте подивимося на реальні замірі. Ось результати тестування типового WordPress-сайту (theme Astra, 12 плагінів, WooCommerce з 500 товарами) на VPS з 2 ядрами та 4 ГБ RAM:

Параметр Без оптимізації OPcache OPcache + APCu + Redis
Час відповіді (TTFB) 1.8 сек 0.7 сек 0.18 сек
Запити/сек (ab -n1000 -c50) 28 85 310
Використання CPU при навантаженні 95-100% 60-70% 25-35%
SQL-запитів на сторінку 47 47 3-5
Споживання RAM 1.2 ГБ 1.4 ГБ 1.8 ГБ

Зверніть увагу: RAM зросла. Кеш - це завжди компроміс між пам'яттю і швидкістю. Але зменшення часу відповіді в 10 разів при додаткових 600 МБ пам'яті - це угода, від якої складно відмовитися.

Налаштування OPcache: 7 параметрів, які змінюють все

Дефолтні налаштування OPcache розраховані на максимальну сумісність, а не на максимальну продуктивність. Ось що варто змінити у вашому php.ini:

  • opcache.memory_consumption = 256 - за замовчуванням 128 МБ, для серйозного проєкту на Laravel чи WordPress з WooCommerce цього мало. Перевіряйте заповненість через opcache_get_status().
  • opcache.max_accelerated_files = 20000 - дефолт 10000, а типовий WordPress з плагінами має 15000+ файлів. Якщо ліміт перевищено, OPcache починає "забувати" файли.
  • opcache.validate_timestamps = 0 - на продакшені вимикайте перевірку змін файлів. Після деплою просто скидайте кеш вручну або через CI/CD-скрипт.
  • opcache.revalidate_freq = 0 - якщо validate_timestamps увімкнено (на staging-сервері), перевіряти зміни при кожному запиті.
  • opcache.interned_strings_buffer = 32 - буфер для інтернованих рядків. PHP повторює багато однакових рядків, і цей буфер дозволяє зберігати їх в одному місці.

Критична помилка, яку я бачу постійно: люди вмикають OPcache на dev-сервері з validate_timestamps=0 і потім годинами не розуміють, чому зміни в коді не застосовуються. На локальній машині - завжди validate_timestamps=1.

PHP-FPM: тонке налаштування воркерів

PHP-FPM має три режими управління процесами: static, dynamic, ondemand. Вибір залежить від вашого трафіку і ресурсів.

Для VPS з 4 ГБ RAM і стабільним трафіком (100-500 відвідувачів на годину) оптимальна конфігурація:

pm = dynamic - створює процеси за потребою в межах заданих лімітів.
pm.max_children = 30 - максимум воркерів. Формула: (RAM - RAM для ОС та БД) / середній розмір процесу PHP. Один воркер WordPress з'їдає приблизно 40-60 МБ.
pm.start_servers = 10 - скільки воркерів стартує одразу.
pm.min_spare_servers = 5 - мінімум "запасних" воркерів.
pm.max_spare_servers = 15 - максимум "запасних".

Як зрозуміти, що воркерів не вистачає? Дивіться лог PHP-FPM. Рядок "server reached pm.max_children setting" - це крик про допомогу. Ваш сервер відхиляє запити, користувачі бачать 502 або 504 помилку, а ви навіть не підозрюєте.

Redis vs APCu vs Memcached: коли що використовувати

Це питання виникає завжди. Коротка відповідь: вони не конкуренти, а команда.

APCu - для простого key-value кешу в межах одного сервера. Нуль конфігурації, максимальна швидкість (читання з тієї ж пам'яті процесу). Ідеальний для кешу конфігурацій, перекладів, маленьких довідників.

Redis - для всього іншого. Сесії (особливо якщо у вас балансувальник і кілька серверів), кеш сторінок, черги задач, pub/sub. Redis зберігає дані на диск, тож переживає перезапуск.

Memcached - легший за Redis, ідеальний якщо вам потрібен тільки key-value кеш без складних структур. Facebook використовує Memcached для кешу в масштабах мільярдів запитів на секунду.

Золоте правило: OPcache - завжди, APCu - на одиночному сервері, Redis - коли проєкт росте і потрібна гнучкість.

А ви впевнені, що ваш хостинг не ігнорує все це?

Ось що мене дивує: більшість веб-розробників витрачають десятки годин на оптимізацію CSS, стискання картинок, вибір "легкої" теми - і повністю ігнорують серверну сторону. Це як полірувати кузов автомобіля, в якого двигун працює на трьох циліндрах з чотирьох.

Перевірте прямо зараз. Створіть файл info.php з одним рядком <?php phpinfo(); ?>, відкрийте його в браузері і знайдіть секцію OPcache. Якщо написано Opcode Caching: Disabled - ваш сайт працює повільніше, ніж міг би, і ви платите за хостинг, який не віддає навіть половини своєї потужності. Питання тільки одне: скільки ще запитів ваш сервер витратить даремно, поки ви читаєте цю статтю?