Оптимизация php для symfony
Symfony - это еще один фреймворк для разработки веб-приложений на языке PHP. Так как он написан на php, то я разберу основные настройки php для большей скорости работы.
Настройки будут для php8-fpm.
В нашем примере PgSQL\Redis\memcached вынесены на другую ВМ. В нашей ВМ CPU 4, RAM 8Gb.
Так как мы пока не знаем, сколько будет пользователй онлайн в единицу времени, будем отталкиваться от 50 слушателей для fpm. Созданим новый файл настройки для fpm
; Имя пула. Можно создать несколько для разных задач.
[symfony_prod]
; Использовать Unix-сокет - меньше накладных расходов, чем TCP
listen = /run/php/php8.x-fpm-symfony.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
; Статический менеджер процессов - дает максимальную производительность,
; так как все процессы создаются заранее и готовы к работе.
; Платим памятью, но на 8 GB это оправдано.
pm = static
; Ключевой параметр! Рассчитываем количество воркеров.
; 1. Средний размер одного воркера Symfony (с предзагрузкой) ~ 40-80MB.
; 2. Выделяем 6 GB под PHP (оставляем 2 GB для ОС, кешей, Nginx и т.д.).
; 3. 6144MB / 70MB ~ 88.
; Берем с запасом, учитывая пиковые нагрузки. Начинаем с 50.
pm.max_children = 50
; Без этого воркеры со временем будут потреблять все больше памяти из-за микро-утечек в коде или расширениях.
; После обработки 1000 запросов воркер будет перезапущен.
pm.max_requests = 1000
; Приоритет процесса. Можно немного повысить, но осторожно.
; pm.priority = 0
; Безопасность и производительность
security.limit_extensions = .php .php8
; Важно для избежания блокировки при высоких нагрузках
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off
php_admin_flag[short_open_tag] = off
; Логирование только критичных ошибок чтобы избежать затрат на I/O
php_admin_value[error_log] = /var/log/php/symfony-prod.log
php_admin_value[log_level] = error
; Устанавливаем корректный umask для файлов, создаваемых PHP
php_admin_value[umask] = 0022
; Защита от переполнения памяти в одном скрипте
php_admin_value[memory_limit] = 256M
OPcache - это необходимость, которая включана по умолчанию, но еще не настроена, эти параметры мы настроим в opcache.ini, обычно это в /etc/php/8.x/fpm/conf.d/10-opcache.ini
zend_extension=opcache.so
; Агрессивные настройки для продакшена
opcache.enable=1
opcache.enable_cli=0 ; Для FPM не нужно
opcache.memory_consumption=512 ; Выделяем 512MB под кеш OPcache! Этого хватит для очень большого проекта.
opcache.interned_strings_buffer=32 ; Больше повторяющихся строк в памяти - меньше её расход.
opcache.max_accelerated_files=30000 ; Современные фреймворки содержат ОЧЕНЬ много файлов.
opcache.validate_timestamps=0 ; ВКЛЮЧАЕМ НА ПРОДАКШЕНЕ! Таймстампы проверяться не будут. Скорость максимальна.
; ВАЖНО: При validate_timestamps=0 кеш НЕ будет обновляться при изменении файлов.
; Очистку кеша (через php-fpm restart или opcache_reset()) нужно делать при каждом деплое автоматически.
opcache.revalidate_freq=0
opcache.fast_shutdown=1
opcache.file_update_protection=0
; Preloading - САМАЯ важная настройка для Symfony
opcache.preload=/var/www/symfony/var/cache/prod/App_KernelProdContainer.preload.php
opcache.preload_user=www-data
; Настройки JIT. Режим tracing лучше всего подходит для сложных приложений.
; Выделяем 256M под буфер JIT. На 4 CPU это хорошее значение.opcache.jit_buffer_size=256M
opcache.jit=1255 ; Алиас для "tracing" режима с максимальным уровнем оптимизации
; Расшифровка 1255: 1 (CPU-specific optimization) | 2 (enable JIT) | 55 (tracing JIT)
; Альтернативно, можно использовать opcache.jit=tracing
Настроим само приложение на symfony, в нём есть .env.prod (.env.local)
APP_DEBUG=0
APP_ENV=prod
Далее сделаем предзагрузку в самой симфони и прочистим кеши
composer install --no-dev --optimize-autoloader --classmap-authoritative --apcu-autoloader
php bin/console cache:clear --env=prod --no-debug
php bin/console cache:warmup --env=prod --no-debug
Флаг --classmap-authoritative создает идеальный автозагрузчик класса, а --apcu-autoloader кеширует его находки в APCu, что еще больше ускоряет автозагрузку.
Убедитесь, что файл var/cache/prod/App_KernelProdContainer.preload.php существует после кеширования. Путь к нему нужно указать в opcache.preload.
Все проекты разные и разные настройки нужны. Вот пример команды, что бы узнать сколько памяти потребляет процес php
# Узнаем средний размер памяти на воркер (RSS)
ps --user www-data -o rss,comm | grep php-fpm | awk '{sum+=$1} END {printf "Средний размер воркера: %.2f MB\n", sum/NR/1024}'
# Расчет: (Общая память - Память под ОС, БД и пр.) / Размер одного воркера
# Пример: (8192 - 2048) / 70 = ~88 воркеров (это теоретический максимум, мы начали с 50).

bitrix24 + nginx + php-fpm
Битрикс шмитрикс, та еще головная боль. Но бизнес требует что бы проект был на битриксе, а ставить их битриксвм у …

Корпоративный почтовый сервер на минималках (postfix + dovecot + freeipa)
Postfix — агент передачи почты (MTA — mail transfer agent). Postfix является свободным программным обеспечением, создавался как альтернатива Sendmail.
Изначально Postfix …

Настрока фаервола nftables
nftables — подсистема ядра Linux, обеспечивающая фильтрацию и классификацию сетевых пакетов/датаграмм/кадров. Включена в ядро Linux, начиная с версии 3.13, выпущенной …