# Производительность По умолчанию FrankenPHP предлагает хороший баланс между производительностью и удобством использования. Однако, используя подходящую конфигурацию, можно существенно улучшить производительность. ## Количество потоков и worker-скриптов По умолчанию FrankenPHP запускает потоков и worker-скриптов (в worker режиме) вдвое больше, чем количество доступных процессорных ядер. Оптимальные значения зависят от структуры вашего приложения, его функциональности и аппаратного обеспечения. Мы настоятельно рекомендуем изменить эти значения. Чтобы найти подходящие параметры, лучше всего провести нагрузочные тесты, имитирующие реальный трафик. Хорошими инструментами для этого являются [k6](https://k6.io) и [Gatling](https://gatling.io). Чтобы настроить количество потоков, используйте опцию `num_threads` в директивах `php_server` и `php`. Для изменения количества worker-скриптов используйте опцию `num` в секции `worker` директивы `frankenphp`. ## Worker режим Включение [Worker режима](worker.md) значительно улучшает производительность, но ваше приложение должно быть адаптировано для совместимости с этим режимом: необходимо создать worker-скрипт и убедиться, что приложение не имеет утечек памяти. ## Избегайте использования musl Статические бинарники, которые мы предоставляем, а также Alpine Linux-вариант официальных Docker-образов используют [библиотеку musl libc](https://musl.libc.org). Известно, что PHP [значительно медленнее работает](https://gitlab.alpinelinux.org/alpine/aports/-/issues/14381) с этой библиотекой по сравнению с традиционной GNU libc, особенно при компиляции в ZTS режиме (потокобезопасный режим), который требуется для FrankenPHP. Кроме того, [некоторые ошибки проявляются исключительно при использовании musl](https://github.com/php/php-src/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen+label%3ABug+musl). В производственной среде настоятельно рекомендуется использовать glibc. Это можно сделать, используя Debian Docker-образы (по умолчанию) и [компилируя FrankenPHP из исходников](compile.md). В качестве альтернативы мы предоставляем статические бинарники, скомпилированные с [аллокатором mimalloc](https://github.com/microsoft/mimalloc), что делает FrankenPHP+musl быстрее (но всё же медленнее, чем FrankenPHP+glibc). ## Настройка среды выполнения Go FrankenPHP написан на языке Go. В большинстве случаев среда выполнения Go не требует особой настройки, но в некоторых ситуациях специфическая конфигурация может улучшить производительность. Рекомендуется установить переменную окружения `GODEBUG` в значение `cgocheck=0` (по умолчанию в Docker-образах FrankenPHP). Если вы запускаете FrankenPHP в контейнерах (Docker, Kubernetes, LXC и т.д.) и ограничиваете доступную память, установите переменную окружения `GOMEMLIMIT` в значение доступного объёма памяти. Для более детальной информации ознакомьтесь с [документацией Go по этой теме](https://pkg.go.dev/runtime#hdr-Environment_Variables). ## `file_server` По умолчанию директива `php_server` автоматически настраивает файловый сервер для обслуживания статических файлов (ресурсов), хранящихся в корневой директории. Эта функция удобна, но имеет издержки. Чтобы отключить её, используйте следующую конфигурацию: ```caddyfile php_server { file_server off } ``` ## Плейсхолдеры Вы можете использовать [плейсхолдеры](https://caddyserver.com/docs/conventions#placeholders) в директивах `root` и `env`. Однако это предотвращает кеширование значений и существенно снижает производительность. По возможности избегайте использования плейсхолдеров в этих директивах. ## `resolve_root_symlink` По умолчанию, если корневая директория документа является символьной ссылкой, она автоматически разрешается FrankenPHP (это необходимо для корректной работы PHP). Если корневая директория документа не является символьной ссылкой, вы можете отключить эту функцию. ```caddyfile php_server { resolve_root_symlink false } ``` Это улучшит производительность, если директива `root` содержит [плейсхолдеры](https://caddyserver.com/docs/conventions#placeholders). В остальных случаях прирост производительности будет минимальным. ## Логи Логирование, безусловно, полезно, но требует операций ввода-вывода и выделения памяти, что значительно снижает производительность. Убедитесь, что вы [правильно настроили уровень логирования](https://caddyserver.com/docs/caddyfile/options#log) и логируете только необходимое. ## Производительность PHP FrankenPHP использует официальный интерпретатор PHP. Все стандартные оптимизации производительности PHP применимы к FrankenPHP. В частности: - убедитесь, что [OPcache](https://www.php.net/manual/en/book.opcache.php) установлен, включён и настроен должным образом; - включите [оптимизацию автозагрузки Composer](https://getcomposer.org/doc/articles/autoloader-optimization.md); - убедитесь, что кеш `realpath` достаточно велик для нужд вашего приложения; - используйте [предварительную загрузку](https://www.php.net/manual/en/opcache.preloading.php). Для более детальной информации ознакомьтесь с [документацией Symfony о производительности](https://symfony.com/doc/current/performance.html) (большинство советов полезны даже если вы не используете Symfony).