SIGN IN SIGN UP
# Производительность
По умолчанию 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).