OPcache: настройка и оптимизация
Что такое OPcache
OPcache — встроенный кеш байт-кода PHP. Файлы .php компилируются в байт-код при первом запросе, сохраняются в памяти. Дальше — не перекомпилируются.
Эффект:
- Laravel грузится в 3-5 раз быстрее
- Меньше нагрузки на CPU
- Больше RPS
Как это работает
Без OPcache:
- Запрос → PHP читает 100+ файлов Laravel
- Компилирует каждый в байт-код
- Выполняет
- Забывает
- Следующий запрос → всё заново
С OPcache:
- Первый запрос → PHP читает и компилирует файлы
- Сохраняет байт-код в shared memory
- Выполняет
- Второй запрос → берёт байт-код из памяти
- В 3-5 раз быстрее
Проверка, включён ли
CLI:
php -i | grep opcache.enable
# opcache.enable => On => On
FPM:
php-fpm8.5 -i | grep opcache.enable
Или создай файл info.php:
<?php
phpinfo();
Открой в браузере, ищи OPcache. Если раздел есть — работает.
Где конфиг
- CLI:
/etc/php/8.5/cli/conf.d/10-opcache.ini - FPM:
/etc/php/8.5/fpm/conf.d/10-opcache.ini
Открой:
sudo nano /etc/php/8.5/fpm/conf.d/10-opcache.ini
Настройки для прода
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.max_wasted_percentage=10
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.save_comments=1
opcache.fast_shutdown=1
Разбор каждой
opcache.enable=1
Включить для FPM.
opcache.enable_cli=0
Отключить для CLI. Composer, artisan, тесты — не кешируют. Иначе кеш CLI забивается мусором.
opcache.memory_consumption=256
256 МБ памяти под кеш. Для Laravel — оптимально. Меньше 128 — мало. Больше 512 — избыточно.
opcache.interned_strings_buffer=16
16 МБ под интернированные строки. Laravel использует много строк — 16 норм.
opcache.max_accelerated_files=20000
Сколько файлов кешируется.
Сколько у Laravel:
find /var/www/skills/api/vendor -name "*.php" | wc -l
# 15000-25000
Ставь 20000-30000. Если меньше — часть файлов не кешируется.
Реальные значения:
- Laravel + зависимости: 15000-25000 файлов
- 20000 — норм
- 30000 — с запасом
opcache.max_wasted_percentage=10
Сколько памяти можно «потерять» перед сбросом. 10% — стандарт.
opcache.validate_timestamps=0
Ключевая настройка для прода.
0— не проверять изменились ли файлы. Быстрее.1— проверять. Медленнее, но при изменении файла кеш обновится.
На проде: 0. Файлы меняются только при деплое, после чего мы сами сбрасываем кеш.
На dev: 1 (или не трогать, по умолчанию).
opcache.revalidate_freq=0
Как часто проверять изменения (в секундах). Работает только если validate_timestamps=1.
opcache.save_comments=1
Сохранять комментарии.
⚠️ Не отключай! Laravel и Symfony используют аннотации в комментариях — роуты, валидация, ORM. Отключишь — всё сломается.
opcache.fast_shutdown=1
Быстрое освобождение памяти. Включи.
JIT (Just-In-Time)
PHP 8.0+ умеет JIT — компиляцию в машинный код во время работы. Ускорение CPU-интенсивных задач.
Настройка:
opcache.jit_buffer_size=128M
opcache.jit=1255
Что значит 1255:
- 1 — использовать трассировку (tracing JIT)
- 2 — включить на всех функциях
- 5 — оптимизация регистров
- 5 — оптимизация памяти
Для веба JIT помогает мало. Основное время — БД и сеть. Для математики, обработки данных — заметно.
Рекомендация:
- Веб-приложения: JIT не обязателен
- API, SaaS: попробуй
jit_buffer_size=64M,jit=1255 - Без JIT: оставь
opcache.jit=disable
Сброс OPcache
validate_timestamps=0 = сброс вручную после деплоя.
Способы:
1. Reload PHP-FPM:
sudo systemctl reload php8.5-fpm
2. Artisan:
php artisan opcache:clear
(нужен пакет appstract/laravel-opcache)
3. Через URL:
Создай /var/www/skills/api/public/opcache-reset.php:
<?php
if (($_GET['key'] ?? '') !== 'your-secret-key') {
http_response_code(403);
exit;
}
opcache_reset();
echo 'OK';
⚠️ Не оставляй без защиты. Лучше удали после первого использования.
В деплой-скрипт добавь:
curl -s https://example.com/opcache-reset.php?key=your-secret-key
rm /var/www/skills/api/public/opcache-reset.php
Проверка работы
Статус через web:
Установи пакет opcache-gui или opcache-status:
git clone https://github.com/amnuts/opcache-gui /var/www/skills/api/public/opcache
Открой в браузере — увидишь статистику:
- Cached scripts — сколько файлов
- Hit rate — % попаданий в кеш
- Used memory — сколько памяти
- Wasted memory — потери
Хорошие показатели:
- Hit rate > 99%
- Wasted memory < 5%
Если hit rate низкий — мало memory_consumption или max_accelerated_files.
Через CLI:
php -r "print_r(opcache_get_status(false));"
Настройка на CLI
Отдельный конфиг для CLI. Не включай кеш — тесты и artisan должны видеть свежий код.
/etc/php/8.5/cli/conf.d/10-opcache.ini:
opcache.enable_cli=0
Проверка после деплоя
1. Кеш сброшен:
curl -s https://example.com/opcache-status
Смотри Cached scripts — должно быть много.
2. Приложение работает:
curl -I https://example.com
# HTTP/1.1 200 OK
3. Логи чистые:
tail -50 /var/log/php8.5-fpm.log
Частые проблемы
1. Изменения в коде не применяются
Причина: validate_timestamps=0, кеш не сбрасывается.
Решение: sudo systemctl reload php8.5-fpm.
2. Cannot redeclare — ошибка после деплоя
Причина: старый байт-код в кеше.
Решение: сброс OPcache.
3. OPcache не кеширует файлы
Причина: max_accelerated_files меньше числа файлов.
Проверка:
php -r "echo opcache_get_status()['opcache_statistics']['num_cached_scripts'];"
Если близко к max_accelerated_files — увеличь.
4. Медленно работает после деплоя
Причина: кеш пустой, файлы компилируются заново.
Решение: это норма. Первый запрос медленнее, дальше быстро.
Практика: свежая установка
1. Открой конфиг:
sudo nano /etc/php/8.5/fpm/conf.d/10-opcache.ini
2. Поставь:
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.fast_shutdown=1
3. Перезагрузи:
sudo systemctl restart php8.5-fpm
4. Проверь:
curl -I https://example.com
5. Замерь скорость:
ab -n 100 -c 10 https://example.com/
Сравни до и после. Должно быть в 2-5 раз быстрее.
Итог
Минимум для прода:
opcache.enable=1opcache.memory_consumption=256opcache.max_accelerated_files=20000opcache.validate_timestamps=0opcache.save_comments=1
После деплоя — sudo systemctl reload php8.5-fpm.
Дальше — PostgreSQL: установка.