Документация Laravel 10.x
Здесь ты найдешь сниппеты по Laravel и полезные советы по веб-разработке.
Laravel Octane увеличивает производительность вашего приложения, обслуживая его с использованием мощных серверов приложений, таких как Open Swoole, Swoole и RoadRunner. Octane загружает ваше приложение один раз, держит его в памяти, а затем подает ему запросы со сверхзвуковой скоростью.
Octane можно установить с помощью менеджера пакетов Composer:
composer require laravel/octane
После установки Octane вы можете выполнить команду Artisan octane:install
, которая установит файл конфигурации Octane в ваше приложение:
php artisan octane:install
Внимание Laravel Octane требует PHP 8.1+.
RoadRunner работает на бинарном файле RoadRunner, построенном с использованием Go. Первый раз, когда вы запускаете сервер Octane на основе RoadRunner, Octane предложит вам загрузить и установить бинарный файл RoadRunner.
Если вы планируете разрабатывать свое приложение с использованием Laravel Sail, вы должны выполнить следующие команды для установки Octane и RoadRunner:
./vendor/bin/sail up ./vendor/bin/sail composer require laravel/octane spiral/roadrunner-cli spiral/roadrunner-http
Затем вы должны запустить оболочку Sail и использовать исполняемый файл rr
, чтобы получить последнюю сборку RoadRunner для Linux:
./vendor/bin/sail shell # Within the Sail shell..../vendor/bin/rr get-binary
После установки бинарного файла RoadRunner вы можете завершить сеанс оболочки Sail. Теперь вам нужно настроить файл supervisor.conf
, используемый Sail для поддержания работы вашего приложения. Для начала выполните команду Artisan sail:publish
:
./vendor/bin/sail artisan sail:publish
Затем обновите директиву command
файла docker/supervisord.conf
вашего приложения, чтобы Sail обслуживал ваше приложение с использованием Octane вместо PHP-сервера разработки:
command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=roadrunner --host=0.0.0.0 --rpc-port=6001 --port=80
Наконец, убедитесь, что исполняемый файл rr
доступен для выполнения, и построите образы Sail:
chmod +x ./rr ./vendor/bin/sail build --no-cache
Если вы планируете использовать сервер приложений Swoole для обслуживания вашего приложения Laravel Octane, вы должны установить расширение PHP для Swoole. Обычно это можно сделать с помощью PECL:
pecl install swoole
Если вы хотите использовать сервер приложений Open Swoole для обслуживания вашего приложения Laravel Octane, вы должны установить расширение PHP для Open Swoole. Обычно это можно сделать с помощью PECL:
pecl install openswoole
Использование Laravel Octane с Open Swoole предоставляет ту же функциональность, что и Swoole, такую как параллельные задачи, тики и интервалы.
Внимание Перед тем как обслуживать приложение Octane через Sail, убедитесь, что у вас установлена последняя версия Laravel Sail, и выполните
./vendor/bin/sail build --no-cache
в корневом каталоге вашего приложения.
В качестве альтернативы вы можете разрабатывать свое приложение Octane на основе Swoole с использованием Laravel Sail, официальной среды разработки Laravel на основе Docker. Laravel Sail включает расширение Swoole по умолчанию. Тем не менее, вам все равно нужно будет настроить файл supervisor.conf
, используемый Sail, чтобы ваше приложение продолжало работать. Чтобы начать, выполните команду Artisan sail:publish
:
./vendor/bin/sail artisan sail:publish
Затем обновите директиву command
файла docker/supervisord.conf
вашего приложения так, чтобы Sail обслуживал ваше приложение с использованием Octane вместо сервера разработки PHP:
command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=swoole --host=0.0.0.0 --port=80
Наконец, построите образы Sail:
./vendor/bin/sail build --no-cache
Swoole поддерживает несколько дополнительных параметров конфигурации, которые вы можете добавить в файл конфигурации octane
, если это необходимо. Поскольку они редко нуждаются в изменениях, эти параметры не включены в файл конфигурации по умолчанию:
'swoole' => [ 'options' => [ 'log_file' => storage_path('logs/swoole_http.log'), 'package_max_length' => 10 * 1024 * 1024, ],],
Сервер Octane можно запустить с помощью команды Artisan octane:start
. По умолчанию эта команда будет использовать сервер, указанный в опции конфигурации server
файла конфигурации octane
вашего приложения:
php artisan octane:start
По умолчанию Octane запустит сервер на порту 8000, поэтому вы можете получить доступ к вашему приложению в веб-браузере по адресу http://localhost:8000
.
По умолчанию приложения, работающие через Octane, создают ссылки с префиксом http://
. Переменная окружения OCTANE_HTTPS
, используемая в файле конфигурации config/octane.php
вашего приложения, может быть установлена в true
при обслуживании вашего приложения через HTTPS. Когда это значение конфигурации установлено в true
, Octane указывает Laravel добавлять префикс https://
ко всем созданным ссылкам:
'https' => env('OCTANE_HTTPS', false),
Примечание Если вы еще не готовы управлять конфигурацией своего сервера или не чувствуете себя уверенно при настройке всех необходимых служб для запуска надежного приложения Laravel Octane, обратитесь к Laravel Forge.
В производственных средах рекомендуется обслуживать ваше приложение Octane через традиционный веб-сервер, такой как Nginx или Apache. Это позволит веб-серверу обслуживать ваши статические ресурсы, такие как изображения и таблицы стилей, а также управлять завершением SSL-сертификата.
В приведенном ниже примере конфигурации Nginx Nginx будет обслуживать статические ресурсы сайта и перенаправлять запросы к серверу Octane, работающему на порту 8000:
map $http_upgrade $connection_upgrade { default upgrade; '' close;} server { listen 80; listen [::]:80; server_name domain.com; server_tokens off; root /home/forge/domain.com/public; index index.php; charset utf-8; location /index.php { try_files /not_exists @octane; } location / { try_files $uri $uri/ @octane; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } access_log off; error_log /var/log/nginx/domain.com-error.log error; error_page 404 /index.php; location @octane { set $suffix ""; if ($uri = /index.php) { set $suffix ?$query_string; } proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header Scheme $scheme; proxy_set_header SERVER_PORT $server_port; proxy_set_header REMOTE_ADDR $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_pass http://127.0.0.1:8000$suffix; }}
Поскольку ваше приложение загружается в память один раз при запуске сервера Octane, любые изменения в файлах вашего приложения не будут отражаться при обновлении браузера. Например, определения маршрутов, добавленные в файл routes/web.php
, не будут отражаться, пока сервер не будет перезапущен. Для удобства вы можете использовать флаг --watch
, чтобы указать Octane автоматически перезапускать сервер при любых изменениях файлов в вашем приложении:
php artisan octane:start --watch
Прежде чем использовать эту функцию, убедитесь, что Node установлен в вашей локальной среде разработки. Кроме того, вы должны установить библиотеку для отслеживания файлов Chokidar в вашем проекте:
npm install --save-dev chokidar
Вы можете настроить каталоги и файлы, которые должны быть отслежены, с использованием опции конфигурации watch
в файле конфигурации config/octane.php
вашего приложения.
По умолчанию Octane будет запускать рабочего приложения для каждого ядра ЦП вашего компьютера. Эти воркеры затем будут использоваться для обслуживания входящих HTTP-запросов по мере их поступления в ваше приложение. Вы можете вручную указать, сколько воркеров вы хотите запустить, используя опцию --workers
при вызове команды octane:start
:
php artisan octane:start --workers=4
Если вы используете сервер приложений Swoole, вы также можете указать, сколько "рабочих задач" вы хотите запустить:
php artisan octane:start --workers=4 --task-workers=6
Чтобы предотвратить случайные утечки памяти, Octane грациозно перезапускает любого воркера после обработки 500 запросов. Чтобы изменить это число, вы можете использовать опцию --max-requests
:
php artisan octane:start --max-requests=250
Вы можете грациозно перезапустить рабочих приложений сервера Octane с использованием команды octane:reload
. Обычно это следует сделать после развертывания, чтобы ваш код был загружен в память и использовался для обслуживания последующих запросов:
php artisan octane:reload
Вы можете остановить сервер Octane с использованием команды Artisan octane:stop
:
php artisan octane:stop
Вы можете проверить текущий статус сервера Octane с использованием команды Artisan octane:status
:
php artisan octane:status
Поскольку Octane загружает ваше приложение один раз и хранит его в памяти при обслуживании запросов, есть несколько моментов, которые следует учесть при построении вашего приложения. Например, методы register
и boot
поставщиков служб вашего приложения будут выполнены только один раз при первоначальной загрузке рабочего процесса запроса. На последующих запросах будет использоваться тот же экземпляр приложения.
В связи с этим следует особенно внимательно относиться к внедрению контейнера служб приложения или запроса в конструктор любого объекта. Таким образом, у этого объекта может быть устаревшая версия контейнера или запроса при последующих запросах.
Octane автоматически обрабатывает сброс любого состояния фреймворка первой стороны между запросами. Однако Octane не всегда знает, как сбросить глобальное состояние, созданное вашим приложением. Поэтому вы должны знать, как строить ваше приложение так, чтобы оно было дружелюбным к Octane. Ниже мы рассмотрим наиболее распространенные ситуации, которые могут вызвать проблемы при использовании Octane.
В общем случае следует избегать внедрения контейнера служб приложения или экземпляра HTTP-запроса в конструкторы других объектов. Например, следующее связывание внедряет весь контейнер служб приложения в объект, который связан как синглтон:
use App\Service;use Illuminate\Contracts\Foundation\Application; /** * Зарегистрируйте любые службы приложения. */public function register(): void{ $this->app->singleton(Service::class, function (Application $app) { return new Service($app); });}
В этом примере, если экземпляр Service
разрешается в процессе загрузки приложения, контейнер будет внедрен в службу, и этот же контейнер будет удерживаться экземпляром Service
при последующих запросах. Это может не являться проблемой для вашего конкретного приложения, однако это может привести к тому, что контейнер неожиданно потеряет привязки, которые были добавлены позже в цикле загрузки или следующим запросом.
В качестве обходного пути вы можете либо прекратить регистрацию связывания как синглтон, либо внедрить замыкание разрешения контейнера в службу, которое всегда разрешает текущий экземпляр контейнера:
use App\Service;use Illuminate\Container\Container;use Illuminate\Contracts\Foundation\Application; $this->app->bind(Service::class, function (Application $app) { return new Service($app);}); $this->app->singleton(Service::class, function () { return new Service(fn () => Container::getInstance());});
Глобальный помощник app
и метод Container::getInstance()
всегда будут возвращать последнюю версию контейнера приложения.
В общем случае следует избегать внедрения контейнера служб приложения или экземпляра HTTP-запроса в конструкторы других объектов. Например, следующее связывание внедряет весь экземпляр запроса в объект, который связан как синглтон:
use App\Service;use Illuminate\Contracts\Foundation\Application; /** * Зарегистрируйте любые службы приложения. */public function register(): void{ $this->app->singleton(Service::class, function (Application $app) { return new Service($app['request']); });}
В этом примере, если экземпляр Service
разрешается в процессе загрузки приложения, HTTP-запрос будет внедрен в службу, и этот же запрос будет удерживаться экземпляром Service
при последующих запросах. Следовательно, все заголовки, входные данные и данные строки запроса будут неверными, а также все остальные данные запроса.
В качестве обходного пути вы можете либо прекратить регистрацию связывания как синглтон, либо внедрить замыкание разрешения запроса в службу, которое всегда разрешает текущий экземпляр запроса. Или, наиболее рекомендуемый подход, просто передавайте конкретную информацию запроса, которую нуждается ваш объект, в один из методов объекта во время выполнения:
use App\Service;use Illuminate\Contracts\Foundation\Application; $this->app->bind(Service::class, function (Application $app) { return new Service($app['request']);}); $this->app->singleton(Service::class, function (Application $app) { return new Service(fn () => $app['request']);}); // Or... $service->method($request->input('name'));
Глобальный помощник request
всегда будет возвращать запрос, который обрабатывается в вашем приложении, и поэтому его можно безопасно использовать в вашем приложении.
Внимание Допустимо использовать типизацию в методах вашего контроллера и замыканиях маршрутов.
В общем случае следует избегать внедрения экземпляра репозитория конфигурации в конструкторы других объектов. Например, следующее связывание внедряет репозиторий конфигурации в объект, который связан как синглтон:
use App\Service;use Illuminate\Contracts\Foundation\Application; /** * Зарегистрируйте любые службы приложения. */public function register(): void{ $this->app->singleton(Service::class, function (Application $app) { return new Service($app->make('config')); });}
В этом примере, если значения конфигурации изменяются между запросами, у этой службы не будет доступа к новым значениям, потому что она зависит от исходного экземпляра репозитория.
В качестве обходного пути вы можете либо прекратить регистрацию связывания как синглтон, либо внедрить замыкание разрешения репозитория конфигурации в класс:
use App\Service;use Illuminate\Container\Container;use Illuminate\Contracts\Foundation\Application; $this->app->bind(Service::class, function (Application $app) { return new Service($app->make('config'));}); $this->app->singleton(Service::class, function () { return new Service(fn () => Container::getInstance()->make('config'));});
Глобальный config
всегда будет возвращать последнюю версию репозитория конфигурации и поэтому безопасен для использования в вашем приложении.
Помните, что Octane хранит ваше приложение в памяти между запросами; следовательно, добавление данных в статически поддерживаемый массив приведет к утечке памяти. Например, следующий контроллер имеет утечку памяти, поскольку каждый запрос к приложению будет продолжать добавлять данные в статический массив $data
:
use App\Service;use Illuminate\Http\Request;use Illuminate\Support\Str; /** * Обработка входящего запроса. */public function index(Request $request): array{ Service::$data[] = Str::random(10); return [ // ... ];}
При построении вашего приложения вы должны особенно внимательно избегать создания таких типов утечек памяти. Рекомендуется отслеживать использование памяти вашего приложения во время локальной разработки, чтобы убедиться, что вы не вводите новые утечки памяти в ваше приложение.
Внимание Эта функция требует Swoole.
При использовании Swoole вы можете выполнять операции параллельно с помощью легких фоновых задач. Это можно сделать с использованием метода concurrently
Octane. Вы можете объединить этот метод с деструктуризацией массива PHP, чтобы получить результаты каждой операции:
use App\Models\User;use App\Models\Server;use Laravel\Octane\Facades\Octane; [$users, $servers] = Octane::concurrently([ fn () => User::all(), fn () => Server::all(),]);
Задачи, выполняемые Octane параллельно, используют "рабочих задач" Swoole и выполняются в полностью разных процессах по сравнению с входящим запросом. Количество доступных рабочих для обработки параллельных задач определяется директивой --task-workers
в команде octane:start
:
php artisan octane:start --workers=4 --task-workers=6
При вызове метода concurrently
вы не должны предоставлять более 1024 задач из-за ограничений, налагаемых системой задач Swoole.
Внимание Эта функция требует Swoole.
При использовании Swoole вы можете регистрировать операции "тиков", которые будут выполняться каждые указанные секунды. Вы можете регистрировать обратные вызовы "тиков" с помощью метода tick
. Первый аргумент, предоставленный методу tick
, должен быть строкой, представляющей имя тикера. Вторым аргументом должна быть область видимости, которая будет вызвана с указанным интервалом.
В этом примере мы зарегистрируем замыкание, которое будет вызываться каждые 10 секунд. Обычно метод tick
следует вызывать в методе boot
одного из поставщиков служб вашего приложения:
Octane::tick('simple-ticker', fn () => ray('Ticking...')) ->seconds(10);
С использованием метода immediate
вы можете указать Octane мгновенно вызывать обратный вызов тика при первоначальной загрузке сервера Octane, а затем каждые N секунд:
Octane::tick('simple-ticker', fn () => ray('Ticking...')) ->seconds(10) ->immediate();
Внимание Эта функция требует Swoole.
При использовании Swoole вы можете использовать драйвер кэша Octane, который обеспечивает скорость чтения и записи до 2 миллионов операций в секунду. Поэтому этот драйвер кэша отлично подходит для приложений, которым необходимы экстремальные скорости чтения / записи из их слоя кэширования.
Этот драйвер кэша работает на основе таблиц Swoole. Все данные, сохраненные в кэше, доступны всем рабочим на сервере. Однако кэшированные данные будут сброшены при перезапуске сервера:
Cache::store('octane')->put('framework', 'Laravel', 30);
Примечание Максимальное количество записей, разрешенное в кэше Octane, можно определить в файле конфигурации
octane
вашего приложения.
Помимо типичных методов, предоставляемых системой кэширования Laravel, драйвер кэша Octane поддерживает кэширование на основе интервалов. Эти кэши автоматически обновляются с указанным интервалом и должны быть зарегистрированы в методе boot
одного из поставщиков служб вашего приложения. Например, следующий кэш будет обновляться каждые пять секунд:
use Illuminate\Support\Str; Cache::store('octane')->interval('random', function () { return Str::random(10);}, seconds: 5);
Внимание Эта функция требует Swoole.
При использовании Swoole вы можете определять и взаимодействовать с собственными произвольными таблицами Swoole. Таблицы Swoole обеспечивают высокую производительность, и данные в этих таблицах могут быть доступны всем рабочим на сервере. Однако данные в них будут потеряны при перезапуске сервера.
Таблицы следует определять в массиве конфигурации tables
файла конфигурации octane
вашего приложения. Пример таблицы, позволяющей максимум 1000 строк, уже настроен для вас. Максимальный размер столбцов строк может быть настроен, указав размер столбца после типа столбца, как показано ниже:
'tables' => [ 'example:1000' => [ 'name' => 'string:1000', 'votes' => 'int', ],],
Для доступа к таблице вы можете использовать метод Octane::table
:
use Laravel\Octane\Facades\Octane; Octane::table('example')->set('uuid', [ 'name' => 'Nuno Maduro', 'votes' => 1000,]); return Octane::table('example')->get('uuid');
Внимание Типы столбцов, поддерживаемые таблицами Swoole:
string
,int
иfloat
.