Laravel 辛烷值

Introduction

Laravel 辛烷值 通过使用高性能应用程序服务器为您的应用程序提供服务来增强应用程序的性能,包括开放Swoole,Swoole, 和RoadRunner. Octane 启动您的应用程序一次,将其保存在内存中,然后以超音速为它提供请求。

Installation

Octane 可以通过 Composer 包管理器安装:

composer require laravel/octane

安装 Octane 后,您可以执行octane:install Artisan 命令,它将 Octane 的配置文件安装到您的应用程序中:

php artisan octane:install

服务器先决条件

Warning Laravel Octane 需要PHP 8.1+.

RoadRunner

RoadRunner 由使用 Go 构建的 RoadRunner 二进制文件提供支持。第一次启动基于 RoadRunner 的 Octane 服务器时,Octane 会为您下载并安装 RoadRunner 二进制文件。

RoadRunner 通过 Laravel Sail

如果您计划使用Laravel 风帆,您应该运行以下命令来安装 Octane 和 RoadRunner:

./vendor/bin/sail up

./vendor/bin/sail composer require laravel/octane spiral/roadrunner

接下来,您应该启动一个 Sail shell 并使用rr 可执行文件以检索最新的基于 Linux 的 RoadRunner 二进制版本:

./vendor/bin/sail shell

# Within the Sail shell...
./vendor/bin/rr get-binary

安装 RoadRunner 二进制文件后,您可以退出 Sail shell 会话。您现在需要调整supervisor.conf Sail 用来保持应用程序运行的文件。首先,执行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

如果您计划使用 Swoole 应用服务器来为您的 Laravel Octane 应用程序提供服务,则必须安装 Swoole PHP 扩展。通常,这可以通过 PECL 完成:

pecl install swoole

开放Swoole

如果您想使用 Open Swoole 应用服务器来为您的 Laravel Octane 应用程序提供服务,您必须安装 Open Swoole PHP 扩展。通常,这可以通过 PECL 完成:

pecl install openswoole

将 Laravel Octane 与 Open Swoole 结合使用可获得 Swoole 提供的相同功能,例如并发任务、滴答和间隔。

Swoole 通过 Laravel Sail

Warning 在通过 Sail 为 Octane 应用程序提供服务之前,请确保您拥有最新版本的 Laravel Sail 并执行./vendor/bin/sail build --no-cache 在您的应用程序的根目录中。

或者,您可以使用以下方法开发基于 Swoole 的 Octane 应用程序Laravel 风帆,Laravel 的官方基于 Docker 的开发环境。 Laravel Sail 默认包含 Swoole 扩展。但是,您仍然需要调整supervisor.conf Sail 用来保持应用程序运行的文件。首先,执行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配置

Swoole 支持一些额外的配置选项,您可以将它们添加到您的octane 配置文件,如果需要的话。因为它们很少需要修改,所以这些选项不包含在默认配置文件中:

'swoole' => [
    'options' => [
        'log_file' => storage_path('logs/swoole_http.log'),
        'package_max_length' => 10 * 1024 * 1024,
    ],
],

服务您的应用程序

Octane 服务器可以通过以下方式启动octane:start 工匠命令。默认情况下,此命令将使用由server 您的应用程序的配置选项octane配置文件:

php artisan octane:start

默认情况下,Octane 将在端口 8000 上启动服务器,因此您可以通过以下方式在 Web 浏览器中访问您的应用程序http://localhost:8000.

通过 HTTPS 服务您的应用程序

默认情况下,通过 Octane 运行的应用程序生成前缀为http://.这OCTANE_HTTPS 环境变量,在您的应用程序中使用config/octane.php 配置文件,可以设置为true 通过 HTTPS 为您的应用程序提供服务时。当此配置值设置为true, Octane 将指示 Laravel 为所有生成的链接添加前缀https://:

'https' => env('OCTANE_HTTPS', false),

通过 Nginx 服务你的应用程序

Note 如果您还没有准备好管理自己的服务器配置,或者不习惯配置运行强大的 Laravel Octane 应用程序所需的所有各种服务,请查看Laravel 锻造.

在生产环境中,您应该在 Nginx 或 Apache 等传统 Web 服务器后面提供 Octane 应用程序。这样做将允许 Web 服务器为您的静态资产(例如图像和样式表)提供服务,并管理您的 SSL 证书终止。

在下面的 Nginx 配置示例中,Nginx 将站点的静态资产和代理请求提供给运行在端口 8000 上的 Octane 服务器:

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 将为您的机器提供的每个 CPU 核心启动一个应用程序请求工作程序。然后,这些工作人员将在进入您的应用程序时用于处理传入的 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:reload 命令。通常,这应该在部署之后完成,以便将新部署的代码加载到内存中并用于为后续请求提供服务:

php artisan octane:reload

停止服务器

您可以使用以下命令停止 Octane 服务器octane:stop 工匠命令:

php artisan octane:stop

检查服务器状态

您可以使用以下命令检查 Octane 服务器的当前状态octane:status 工匠命令:

php artisan octane:status

依赖注入和 Octane

由于 Octane 会启动您的应用程序一次并在处理请求时将其保存在内存中,因此在构建应用程序时您应该考虑一些注意事项。例如,registerboot 您的应用程序服务提供者的方法只会在请求工作者最初启动时执行一次。在后续请求中,相同的应用程序实例将被重用。

鉴于此,在将应用程序服务容器或请求注入任何对象的构造函数时应特别小心。通过这样做,该对象可能具有容器的陈旧版本或对后续请求的请求。

Octane 将自动处理请求之间任何第一方框架状态的重置。但是,Octane 并不总是知道如何重置应用程序创建的全局状态。因此,您应该了解如何以 Octane 友好的方式构建您的应用程序。下面,我们将讨论使用 Octane 时可能导致问题的最常见情况。

容器注入

通常,您应该避免将应用程序服务容器或 HTTP 请求实例注入到其他对象的构造函数中。例如,以下绑定将整个应用程序服务容器注入到一个绑定为单例的对象中:

use App\Service;
use Illuminate\Contracts\Foundation\Application;

/**
 * Register any application services.
 */
public function register(): void
{
    $this->app->singleton(Service::class, function (Application $app) {
        return new Service($app);
    });
}

在这个例子中,如果Service 实例在应用程序启动过程中解析,容器将被注入到服务中,同一个容器将由Service 后续请求的实例。这may 对于您的特定应用程序来说不是问题;但是,它可能会导致容器意外丢失在引导周期后期或通过后续请求添加的绑定。

作为变通方法,您可以停止将绑定注册为单例,或者可以将容器解析器闭包注入到始终解析当前容器实例的服务中:

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;

/**
 * Register any application services.
 */
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 helper 将始终返回应用程序当前正在处理的请求,因此可以安全地在您的应用程序中使用。

Warning 类型提示是可以接受的Illuminate\Http\Request 控制器方法和路由闭包上的实例。

配置库注入

通常,您应该避免将配置存储库实例注入到其他对象的构造函数中。例如,以下绑定将配置存储库注入到绑定为单例的对象中:

use App\Service;
use Illuminate\Contracts\Foundation\Application;

/**
 * Register any application services.
 */
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;

/**
 * Handle an incoming request.
 */
public function index(Request $request): array
{
    Service::$data[] = Str::random(10);

    return [
        // ...
    ];
}

在构建您的应用程序时,您应该特别注意避免产生这些类型的内存泄漏。建议您在本地开发期间监控应用程序的内存使用情况,以确保您不会在应用程序中引入新的内存泄漏。

并发任务

Warning 此功能需要Swoole.

使用 Swoole 时,您可以通过轻量级后台任务并发执行操作。您可以使用 Octane 的concurrently 方法。您可以将此方法与 PHP 数组解构相结合来检索每个操作的结果:

use App\User;
use App\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 方法,由于 Swoole 任务系统的限制,您不应提供超过 1024 个任务。

刻度和间隔

Warning 此功能需要Swoole.

使用 Swoole 时,您可以注册每指定秒数执行的“滴答”操作。您可以通过以下方式注册“tick”回调tick 方法。提供给的第一个参数tick method 应该是一个代表代码名称的字符串。第二个参数应该是将在指定时间间隔调用的可调用对象。

在此示例中,我们将注册一个每 10 秒调用一次的闭包。通常,tick 方法应该在boot 您的应用程序服务提供商之一的方法:

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

使用immediate 方法,您可以指示 Octane 在 Octane 服务器最初启动时立即调用 tick 回调,此后每隔 N 秒:

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

辛烷缓存

Warning 此功能需要Swoole.

使用 Swoole 时,您可以利用 Octane 缓存驱动程序,它提供每秒高达 200 万次操作的读写速度。因此,对于需要从缓存层读取/写入速度极快的应用程序,此缓存驱动程序是绝佳选择。

此缓存驱动程序由Swoole表.存储在缓存中的所有数据都可供服务器上的所有工作人员使用。但是,当服务器重新启动时,缓存的数据将被刷新:

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

Note Octane 缓存中允许的最大条目数可以在您的应用程序的octane 配置文件。

缓存间隔

除了 Laravel 缓存系统提供的典型方法外,Octane 缓存驱动程序还具有基于间隔的缓存功能。这些缓存在指定的时间间隔内自动刷新,并应在boot 您应用程序的服务提供商之一的方法。例如,以下缓存将每五秒刷新一次:

use Illuminate\Support\Str;

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

Tables

Warning 此功能需要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');

Warning Swoole表支持的列类型有:string,int, 和float.

豫ICP备18041297号-2