Настройка производительности PHP 8: OpCache и JIT
Ваше приложение на PHP 8 работает медленно под нагрузкой. Вы оптимизировали запросы, добавили кэширование, но время отклика всё ещё велико. Возможно, причина в накладных расходах самого PHP. Две мощные функции — OpCache и JIT — могут значительно ускорить ваш код, но только при правильной настройке. Это руководство объясняет, как они работают, и как настроить их для реальных нагрузок.
Что такое OpCache и почему это важно
PHP — интерпретируемый язык: каждый запрос обычно парсит и компилирует ваши исходные файлы в байт-код перед выполнением. OpCache сохраняет этот скомпилированный байт-код в разделяемой памяти, поэтому последующие запросы пропускают парсинг и компиляцию. Результат? Снижение нагрузки на CPU и ускорение отклика.
OpCache включён по умолчанию во многих production-конфигурациях, но стандартные настройки консервативны. Их тонкая настройка может дать 2–3-кратный прирост пропускной способности для приложений, ограниченных CPU.
Ключевые директивы конфигурации OpCache
- opcache.enable: Установите 1 для включения. (По умолчанию: 1 в production, 0 в CLI, если не переопределено.)
- opcache.memory_consumption: Размер разделяемой памяти в МБ. Начните со 128 МБ; увеличьте, если видите высокое
opcache.memory_usage. - opcache.max_accelerated_files: Максимальное количество кэшируемых файлов. Установите простое число, большее общего числа PHP-файлов (например, 10007).
- opcache.validate_timestamps: Если 1, PHP проверяет временные метки файлов на изменения. Установите 0 в production, чтобы избежать вызовов stat; после деплоя необходимо вручную очищать кэш.
- opcache.revalidate_freq: Как часто (в секундах) проверять временные метки, если validate_timestamps=1. Установите 0 для разработки, 60+ для production.
- opcache.interned_strings_buffer: Память для интернированных строк (МБ). Увеличьте до 16 или 32 для больших приложений.
- opcache.fast_shutdown: Устарело в PHP 7.2+, удалено в PHP 8.0. Игнорируйте.
- opcache.preload: Путь к скрипту предзагрузки (PHP 7.4+). Предзагрузка компилирует и кэширует файлы при старте, устраняя накладные расходы на каждый запрос для критических классов.
Рекомендуемые настройки OpCache для production
; php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.interned_strings_buffer=32
opcache.preload=/path/to/preload.php
opcache.preload_user=www-data
После изменения настроек перезапустите PHP-FPM. Отслеживайте с помощью opcache_get_status() для проверки попаданий и использования памяти.
Понимание JIT в PHP 8
JIT (Just-In-Time) компиляция делает шаг дальше, чем OpCache: она компилирует байт-код в машинный код во время выполнения. Это может значительно ускорить ресурсоёмкие задачи, такие как математические вычисления, но мало помогает типичным веб-запросам, где преобладает ввод-вывод (база данных, файловая система, сеть).
JIT является частью OpCache, поэтому сначала нужно включить OpCache. В PHP 8 JIT настраивается через opcache.jit и opcache.jit_buffer_size.
Директивы конфигурации JIT
- opcache.jit: Управляет режимом JIT. Используйте
tracing(по умолчанию) илиfunction. Значение — 4-значный код CRTO:CRTO, где C=оптимизация под конкретный CPU, R=распределение регистров, T=триггер, O=уровень оптимизации. Для большинства приложений подходитopcache.jit=tracing. - opcache.jit_buffer_size: Память для JIT-кода в байтах. Начните с 64M или 128M. Если установлено 0, JIT отключён.
- opcache.jit_hot_loop, opcache.jit_hot_func, opcache.jit_hot_return, opcache.jit_hot_side_exit: Пороги для определения горячего кода. Значения по умолчанию обычно подходят.
Рекомендуемые настройки JIT
opcache.jit=tracing
opcache.jit_buffer_size=128M
Примечание: JIT работает только при включённом OpCache. В CLI может потребоваться установить opcache.enable_cli=1 для тестирования JIT.
OpCache против JIT: когда что использовать
| Функция | OpCache | JIT |
|---|---|---|
| Основное преимущество | Кэширует скомпилированный байт-код | Компилирует байт-код в машинный код |
| Лучше всего для | Все PHP-приложения | Ресурсоёмкие, длительные скрипты |
| Влияние на I/O-приложения | Высокое (снижает парсинг/компиляцию) | Низкое или отсутствует |
| Накладные расходы памяти | Умеренные | Дополнительный буфер |
| Сложность | Низкая | Средняя |
Пошаговое руководство по настройке
- Включите OpCache с рекомендуемыми настройками выше.
- Отслеживайте OpCache с помощью
opcache_get_status()или инструментов вроде OpCache GUI. Стремитесь к проценту попаданий выше 99%. - Настройте память, если
opcache.memory_usageблизко к лимиту. - Рассмотрите предзагрузку для крупных фреймворков (Laravel, Symfony). Создайте скрипт предзагрузки, который подключает часто используемые классы.
- Включите JIT только если ваше приложение ограничено CPU. Протестируйте с JIT и без него, чтобы измерить эффект.
- Проведите бенчмарки с помощью инструментов вроде
ab,wrkилиsiege. Сравните запросы в секунду и задержку. - Развёртывайте изменения постепенно и следите за логами ошибок.
Распространённые ошибки и лучшие практики
- Не отключайте validate_timestamps в разработке: Вы потратите время на выяснение, почему изменения кода не вступают в силу.
- Очищайте OpCache при деплое: Если validate_timestamps=0, вы должны сбросить OpCache (например, перезапустив PHP-FPM или вызвав
opcache_reset()). - JIT — не серебряная пуля: Для типичных CRUD-приложений OpCache сам по себе даёт большую часть выигрыша.
- Следите за памятью: Буфер JIT и память OpCache увеличивают потребление PHP. Убедитесь, что на сервере достаточно RAM.
- Используйте предзагрузку осторожно: Предзагруженные файлы всегда в памяти; избегайте предзагрузки всего.
FAQ
Улучшает ли JIT производительность всех PHP-приложений?
Нет. JIT помогает при ресурсоёмких задачах, таких как сложные вычисления или обработка данных. Для I/O-приложений (запросы к базе данных, вызовы API) выигрыш минимален. OpCache сам по себе часто даёт наибольшее ускорение.
Как узнать, работает ли OpCache?
Проверьте phpinfo() на статус OpCache или вызовите opcache_get_status() в скрипте. Ищите opcache_enabled => true и высокое количество hits относительно misses.
Можно ли использовать JIT с PHP 7?
Нет. JIT появился в PHP 8.0. PHP 7 поддерживает только OpCache. Если вы на PHP 7, сосредоточьтесь на настройке OpCache и рассмотрите обновление до PHP 8 для JIT и других улучшений производительности.
Готовы проанализировать производительность вашего сервера? Ознакомьтесь с нашим Анализатором логов Nginx, чтобы получить информацию из логов доступа и выявить узкие места.