• Время чтения ~6 мин
  • 21.08.2023

Laravel Octane - что, как и почему

Тейлор Отвелл уже показал последний пакет Laravel с открытым исходным кодом, Octane, во время своего выступления в Laracon Online, но сегодня новый пакет доступен на GitHub для бета-тестирования.

В этом сообщении блога я собираюсь изучить Laravel Octane и рассказать вам, что это такое, как вы можете установить и использовать его, и почему он вам может понадобиться.

Отказ: Laravel Octane все еще является бета-версией программного обеспечения и пока не должен использоваться в производстве!

Что такое Laravel Octane?

Laravel Octane — это пакет с открытым исходным кодом, который повысит производительность вашего приложения Laravel. Laravel Octane требует PHP 8, поэтому, если вы все еще используете 7.x, вам необходимо обновить версию PHP. Под капотом Octane использует :Swoole Swoole и RoadRunner RoadRunner - два сервера приложений, которые заботятся об обслуживании и загрузке вашего приложения Laravel. Почему быстрее, спросите вы. Позвольте мне объяснить.

В традиционном PHP-приложении, которое обслуживается через веб-сервер, такой как nginx, каждый входящий запрос будет порождать PHP-FPM worker. Это означает, что каждый запрос запускает один отдельный процесс PHP, который будет выполнять все необходимые задачи для обслуживания этого одного запроса.

В случае с Laravel это означает, что фреймворк должен быть загружен, все поставщики услуг регистрируют свои сервисы в контейнере, все провайдеры загружаются сами, запрос проходит через список классов промежуточного программного обеспечения, попадает в ваш контроллер, представление визуализируется и т. д., пока мы в конечном итоге не получим ответ от нашего сервера.

С :Swoole Swoole или RoadRunner RoadRunner у нас по-прежнему есть воркер для каждого входящего HTTP-запроса, но все они используют одну и ту же загруженную платформу. Это означает, что только первый входящий запрос будет загружать фреймворк (включая всех поставщиков услуг и т. д.), в то время как каждый второй запрос может использовать готовый фреймворк. И это то, что делает Octane таким безумно быстрым.

Начало работы с Laravel Octane Поскольку Laravel Octane

является пакетом, вам необходимо установить его как зависимость от вашего конкретного приложения. Вы можете сделать это через composer:

composer require laravel/octane\

После того, как вы установили Octane в свое приложение, обязательно запустите php artisan octane:install. Это позволит опубликовать конфигурационный файл Octane, а также добавить rr в .gitignore него двоичный файл RoadRunner RoadRunner.

Как я уже сказал, Octane собирается опубликовать свой конфигурационный файл, который выглядит следующим образом:

return [
    /*
    |--------------------------------------------------------------------------
    | Octane Server
    |--------------------------------------------------------------------------
    |
    | This value determines the default "server" that will be used by Octane
    | when starting, restarting, or stopping your server via the CLI. You
    | are free to change this to the supported server of your choosing.
    |
    */
    'server' => env('OCTANE_SERVER', 'roadrunner'),
    /*
    |--------------------------------------------------------------------------
    | Force HTTPS
    |--------------------------------------------------------------------------
    |
    | When this configuration value is set to "true", Octane will inform the
    | framework that all absolute links must be generated using the HTTPS
    | protocol. Otherwise your links may be generated using plain HTTP.
    |
    */
    'https' => env('OCTANE_HTTPS', false),
    /*
    |--------------------------------------------------------------------------
    | Octane Слушатели Одной из особенностей Octane, которая еще не была задокументирована, является возможность регистрировать пользовательские прослушиватели
    |--------------------------------------------------------------------------
    |
    | All of the event listeners for Octane's events are defined below. These
    | listeners are responsible for resetting your application's state for
    | the next request. You may even add your own listeners to the list.
    |
    */
    'listeners' => [
        WorkerStarting::class => [
            EnsureUploadedFilesAreValid::class,
        ],
        RequestReceived::class => [
            ...Octane::prepareApplicationForNextOperation(),
            ...Octane::prepareApplicationForNextRequest(),
            //
        ],
        RequestHandled::class => [
            //
        ],
        RequestTerminated::class => [
            //
        ],
        TaskReceived::class => [
            ...Octane::prepareApplicationForNextOperation(),
            //
        ],
        TickReceived::class => [
            ...Octane::prepareApplicationForNextOperation(),
            //
        ],
        OperationTerminated::class => [
            FlushTemporaryContainerInstances::class,
            // DisconnectFromDatabases::class,
            // CollectGarbage::class,
        ],
        WorkerErrorOccurred::class => [
            ReportException::class,
            StopWorkerIfNecessary::class,
        ],
        WorkerStopping::class => [
            //
        ],
    ],
    /*
    |--------------------------------------------------------------------------
    | Warm / Flush Bindings
    |--------------------------------------------------------------------------
    |
    | The bindings listed below will either be pre-warmed when a worker boots
    | or they will be flushed before every new request. Flushing a binding
    | will force the container to resolve that binding again when asked.
    |
    */
    'warm' => [
        ...Octane::defaultServicesToWarm(),
    ],
    'flush' => [
        //
    ],
    /*
    |--------------------------------------------------------------------------
    | Garbage Collection Threshold
    |--------------------------------------------------------------------------
    |
    | When executing long-lived PHP scripts such as Octane, memory can build
    | up before being cleared by PHP. You can force Octane to run garbage
    | collection if your application consumes this amount of megabytes.
    |
    */
    'garbage' => 50,
    /*
    |--------------------------------------------------------------------------
    | Maximum Execution Time
    |--------------------------------------------------------------------------
    |
    | (info) 0 means no maximum limit
    |
    */
    'max_execution_time' => 30,
    /*
    |--------------------------------------------------------------------------
    | Octane Cache Table
    |--------------------------------------------------------------------------
    |
    | While using :Swoole Swoole, you may leverage the Octane cache, which is powered
    | by a :Swoole Swoole table. You may set the maximum number of rows as well as
    | the number of bytes per row using the configuration options below.
    |
    */
    'cache' => [
        'rows' => 1000,
        'bytes' => 10000,
    ],
    /*
    |--------------------------------------------------------------------------
    | Octane :Swoole Swoole Tables
    |--------------------------------------------------------------------------
    |
    | While using :Swoole Swoole, you may define additional tables as required by the
    | application. These tables can be used to store data that needs to be
    | quickly accessed by other workers on the particular :Swoole Swoole server.
    |
    */
    'tables' => [
        'example:1000' => [
            'name' => 'string:1000',
            'votes' => 'int',
        ],
    ],
];

Далее вам нужно решить для себя, хотите ли вы использовать RoadRunner RoadRunner или :Swoole Swoole. Затем можно настроить сервер приложений, который вы хотите использовать, настроив server ключ в файле конфигурации. Это может быть swooleлибо , либо roadrunner.

RoadRunner RoadRunner

RoadRunner RoadRunner is an application server that is written in Go, that does not have any other dependencies within PHP itself. Choose RoadRunner RoadRunner, if you do not want to install additional PHP extensions. You can install RoadRunner RoadRunner through composer, like this:

composer require spiral/roadrunner

:Swoole Swoole

:Swoole Swoole comes with a couple of nice benefits, that RoadRunner RoadRunner can not provide. As :Swoole Swoole is an extension on top of PHP, PHP itself gains some cool new features, such as "ticks" and "coroutines", which I'm going to cover in a bit. These features are not available with RoadRunner RoadRunner, so if you want to make use of them, you should go with :Swoole Swoole.

You can install the :Swoole Swoole extension using:

pecl install swoole

During the installation, you will be asked if you want to have support for HTTP2, curl, JSON, and open_ssl within :Swoole Swoole. You can safely stick to the default values here (which are off) as those settings only affect things like coroutines. You will still be able to use curl, JSON, and everything else.

Запуск Octane После того, как вы установили RoadRunner или Swoole и определили его в своем octane.php конфигурационном файле, вы можете запустить Octane

Once you have installed RoadRunner RoadRunner or :Swoole Swoole, and defined it in your octane.php configuration file, you can start Octane and let it serve your Laravel application. The Octane server can be started with:

php artisan octane:start

По умолчанию Octane запускает сервер через порт 8000, поэтому вы можете получить доступ к своему приложению в браузере через http://localhost:8000.

Так что вперед, посетите этот маршрут и посмотрите, как летит ваше приложение Laravel! Если вы сделаете несколько запросов к приложению, вы увидите, что первый немного медленнее - именно там загружается фреймворк, в то время как другие заметно быстрее, так как они могут использовать загруженный фреймворк из памяти.

200 GET / .............. 14.23 ms
200 GET / ..............  1.93 ms
200 GET / ..............  2.06 ms

Внесение изменений

в код Если теперь вы пойдете и внесете изменения в код - например, добавите новый /test маршрут - и попытаетесь нажать на этот URL-адрес, вы получите 404! И это потому, что запрос по-прежнему использует фреймворк (и все его маршруты/код), который был загружен после запуска сервера Octane. Поэтому, чтобы увидеть это изменение кода, вам нужно перезапустить сервер Octane. Поскольку это очень громоздко делать во время разработки, Octane поставляется с хорошим способом автоматически следить за изменениями в вашей кодовой базе и автоматически перезапускать сервер Octane.

Чтобы это работало, обязательно установите Chokidar - библиотеку наблюдения за файлами на основе NodeJS:Затем вы можете запустить сервер Octane в режиме «наблюдения», например

npm install --save-dev chokidar

:

php artisan octane:start --watch

Теперь в следующий раз, когда вы внесете изменения в свою кодовую базу, это будет обнаружено, и Octane перезапустит рабочие процессы для запросов, и вы сразу же увидите свои изменения.

Настройка рабочих

рук Говоря о работниках - по умолчанию Octane будет запускать один рабочий для каждого ядра процессора, которое у вас есть. Но вы также можете изменить это, передав --workers опцию командеoctane:start:

php artisan octane:start --workers=2

:Swoole Специфические функции

As I mentioned, Octane comes with a couple of :Swoole Специфические функции, so lets take a look at those, as I think they are very interesting.

Параллельные задачи Octane

позволяет выполнять несколько задач одновременно. Это означает, что они будут выполняться одновременно и будут возвращены, как только все задачи будут выполнены.

Вот пример, взятый из документации Octane на GitHub:

use App\User;
use App\Server;
use Laravel\Octane\Facades\Octane;
[$users, $servers] = Octane::concurrently([
    fn () => User::all(),
    fn () => Server::all(),
]);

Итак, в этом примере мы получаем всех пользователей и все серверы одновременно. Чтобы прояснить это, вот еще один пример:

Octane::concurrently([
	    function () {
		    	sleep(0.5);
		    	return 1;
	    },
	    function () {
		    	sleep(1);
		    	return 2;
	    },
	]);

Мы выполняем две «задачи» одновременно, и PHP продолжит оценку кода, как только обе задачи будут завершены. Одна задача ждет 0,5 секунды, другая — 1 секунду. Поскольку они оцениваются одновременно, в двух отдельных задачах, PHP будет ждать ровно 1 секунду (а не 1,5), пока оба результата не будут доступны. Эта функция — отличный способ одновременного выполнения нескольких небольших задач.

Как и в случае с опцией--workers, вы также можете настроить количество октана--task-workers, которое должно быть доступным.

Тики / Интервалы

Octane in combination with :Swoole Swoole, allows you to register ticks - which are operations that will automatically be executed at a given interval. Similar to the setInterval method in JavaScript. Unfortunately, there's no way to stop those ticks at the moment, but you can register them within your application like this:

Octane::tick('simple-ticker', fn () => ray('Ticking...'))
        ->seconds(10);

Октановый кэш

Another new feature within Octane and :Swoole Swoole is a new cache driver. This cache driver, according to the official documentation, provides read and write speeds of up to 2 million operations per second. Behind the scenes, :Swoole Swoole is caching the data in a shared memory using :Swoole Swoole Tables, which can be accessed across all workers. When the server restarts, the cached data will be flushed though, as the cache is only persisted in memory.

Чтобы использовать этот кеш, вы можете получить к нему доступ через octane хранилище кэша на фасаде кэша, например

Cache::store('octane')->put('framework', 'Laravel', 30);

Another cool new addition, that is :Swoole Swoole and Octane specific is the ability of a "cache interval". This allows you to store information in the Octane cache and refresh the data in a given interval:

use Illuminate\Support\Str;
Cache::store('octane')->interval('random', function () {
    return Str::random(10);
}, seconds: 5)

Octane Tables Основываясь на функции Swoole Tables, вы можете создавать свои собственные таблицы, к которым вы хотите получить доступ в своих приложениях Octane

Built upon the feature of :Swoole Swoole Tables, you can create your own tables that you want to access within your Octane applications. These tables have the same performance benefit as a Cache would have, by allowing you to save data in a structured way. Keep in mind that all data that you store within such a table will be lost when the server restarts though.

Чтобы настроить таблицу, вы можете создать запись в tables разделе вашего octane.php конфигурационного файла:

'tables' => [
    'example:1000' => [
        'name' => 'string:1000',
        'votes' => 'int',
    ],
],

В этом примере мы определяем таблицу с именем example, которая может содержать не более 1.000 записей/строк. Структура этой таблицы представляет собой , которая представляет собой nameстроку с максимальной длиной 1000, и votes, которая является целым числом.

Чтобы записать данные в эту таблицу, мы можем использовать метод:Octane::table

use Laravel\Octane\Facades\Octane;
Octane::table('example')->set('a-unique-identifier', [
    'name' => 'Marcel Pociot',
    'votes' => 1000,
]);

И чтобы извлечь данные, мы можем использовать get метод в таблице, например

return Octane::table('example')->get('a-unique-identifier');

:Предостережения с Octane Есть несколько вещей, на которые вам нужно обратить внимание, когда вы хотите либо подготовить существующее приложение к Octane

, либо начать создавать новое приложение с нуля.

Поскольку Octane хранит фреймворк в памяти всех работников, такие вещи, как все поставщики услуг приложений, будут зарегистрированы и загружены только один раз. В то время как Octane заботится о сбросе состояния собственных пакетов (включая Inertia), Octane не может сбросить глобальное состояние, которое может быть в вашем собственном коде приложения.

Официальная документация, которую в настоящее время можно найти на GitHub , содержит некоторые из наиболее распространенных сценариев, на которые следует обратить внимание.

Слушатели Одной из особенностей Octane, которая еще не была задокументирована, является возможность регистрировать пользовательские прослушиватели

всякий раз, когда что-то происходит на сервере приложений в Octane. Вы можете подключиться к следующим событиям:

  • WorkerStarting
  • ЗапросПолучено
  • RequestHandled
  • RequestTerminated
  • ЗадачаПолучено
  • ТикПолучил
  • OperationTerminated
  • WorkerErrorПроизошло
  • WorkerStop

Чтобы прикрепить прослушиватели к этим событиям, вы можете добавить их в свой конфигурационный octane.php файл.

Подогрев и промывка

службы При загрузке нового рабочего процесса Octane можно указать список привязок/служб контейнера, которые необходимо «разогреть» в процессе загрузки. Это означает, что после загрузки воркера сервисный контейнер уже сделает указанные сервисы доступными, чтобы следующие запросы могли немедленно получить к ним доступ.

У Octane уже есть список внутренних сервисов, которые он поддерживает во время каждого процесса загрузки воркераoctane.php, но вы можете добавить свои собственные сервисы в warm раздел конфигурационного файла.

Аналогичным образом, вы также можете определить список служб, которые вы хотите очистить, прежде чем поступит новый запрос. Это может быть полезно для служб, которыми манипулируют в ходе запроса, и которые вы хотите сбросить до исходного/выгруженного состояния при поступлении нового запроса.

Октановые маршруты

Если Octane еще не дает вам достаточного прироста скорости, вы даже можете выжать из него немного больше, используя маршрутизацию, встроенную прямо в Octane. Вы можете определить пользовательский маршрут Octane через фасад Octane следующим образом:Эти маршруты очень быстрые, потому что они полностью пропускают систему маршрутизации Laravels (поэтому эти маршруты не предоставляют никакого промежуточного программного обеспечения), что может быть полезно для конечных точек,

Octane::route('GET', '/fast', function() {
    
});

которым нужно предоставлять данные только очень быстро.

Так как HTTP-ядро в Laravel не используется для этих запросов, вам нужно вернуть объект Symfony Response самостоятельно, например

use Symfony\Component\HttpFoundation\Response;
Octane::route('GET', '/faster', function() {
    return new Response('Hello from Octane.');
});

:Все поставщики услуг, конечно, загружены и доступны, так что вы все еще можете использовать эти сервисы, выполнять запросы Eloquent и т.д.

Хорошо... так почему же Октан?

Laravel Octane определенно даст вашему приложению Laravel большой прирост производительности - а мы все любим повышение производительности, не так ли? Нужен ли нам этот прирост производительности? Ну, может быть, я думаю, это зависит от приложения, которое вы запускаете. Но что более важно для меня, так это тот факт, что Laravel (в очередной раз) продвигает текущее состояние PHP. Octane - это не только пакет, требующий как минимум PHP 8, но он также продвигает захватывающие новые функции в мире PHP, такие как сопрограммы, тики и в целом мышление обслуживания вашего собственного приложения с помощью команды artisan.

Я с нетерпением жду будущего Octane!

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297