Laravel 9.x Laravel Octane

イントロダクション

Laravel Octane(オクタン)は、Open SwooleSwooleRoadRunnerなどの高性能なアプリケーションサーバを使用し、アプリケーションを提供することで、アプリケーションのパフォーマンスを向上させます。Octaneはアプリケーションを一度起動したら、メモリ内に保持し、そして超音速でリクエストを送り返します。

インストール

Octaneは、Composerパッケージマネージャでインストールできます。

composer require laravel/octane

Octaneをインストールしたら、octane:install Artisanコマンドを実行してください。これにより、オクタンの設定ファイルをアプリケーションへインストールします。

php artisan octane:install

サーバ要件

Warning!! Laravel Octaneは、PHP8.0以上が必要です。

RoadRunner

RoadRunnerは、Goにより構築されたRoadRunnerバイナリで動作します。初めてRoadRunnerベースのオクタンサーバを起動するとき、OctaneはRoadRunnerバイナリをダウンロードしてインストールするよう指示します。

Laravel SailによるRoadRunner

Laravel Sailを使用してアプリケーションを開発予定の場合は、OctaneとRoadRunnerをインストールする、以下のコマンドを実行する必要があります。

./vendor/bin/sail up

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

次に、Sailシェルを起動し、rr実行可能ファイルを使用して、RoadRunnerバイナリのLinuxベースの最新ビルドを取得します。

./vendor/bin/sail shell

# Sailシェルの中で実行
./vendor/bin/rr get-binary

RoadRunnerのバイナリをインストールしたら、Sailシェルセッションを終了してください。アプリケーションを実行し続けるためにSailにより使用される、supervisor.confファイルを調整する必要があります。手始めに、sail:publish Artisanコマンドを実行してください。

./vendor/bin/sail artisan sail:publish

次に、アプリケーションのdocker/supervisord.confファイルのcommandディレクティブを更新し、Sailが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アプリケーションを提供する予定の場合は、Swool PHP拡張をインストールする必要があります。通常、これはPECLで行います。

pecl install swoole

Laravel SailによるSwoole

Warning!! Sailを介してOctaneアプリケーションを動作させる前に、最新バージョンのLaravel Sailであることを確認し、アプリケーションのルートディレクトリ内で./vendor/bin/sail build --no-cacheを実行してください。

あるいは、Laravelの公式Dockerベースの開発環境であるLaravel Sailを使用して、SwooleベースのOctaneアプリケーションを開発できます。Laravel Sailは、デフォルトでSwoole拡張を含んでいます。ただし、アプリケーションを実行し続けるためにSailが使用する、supervisor.confファイルを調整する必要があります。手始めに、sail:publish Artisanコマンドを実行してください。

./vendor/bin/sail artisan sail:publish

次に、アプリケーションのdocker/supervisord.confファイルのcommandディレクティブを更新し、Sailが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 Configuration

Swooleは追加設定オプションをサポートしており、必要に応じてoctane設定ファイルへ追加できます。これらのオプションはほとんど変更する必要がないため、デフォルトのコンフィギュレーションファイルには含まれていません。

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

アプリケーションの提供

Octaneサーバはoctane:start Artisanコマンドで起動できます。このコマンドは、デフォルトでアプリケーションのoctane設定ファイルのserver設定オプションで指定したサーバを利用します。

php artisan octane:start

Octaneはデフォルトで、ポート8000​​のサーバを起動するので、Webブラウザからhttp://localhost:8000で、アプリケーションへアクセスできます。

HTTPSを使用するアプリケーションの提供

デフォルトでは、Octaneを介して実行されているアプリケーションは、http://を先頭につけたリンクを生成します。アプリケーションのconfig/octane.php設定ファイル内で使用されているOCTANE_HTTPS環境変数は、HTTPS経由でアプリケーションのサービスを提供する場合、trueと設定します。この設定値がtrueに設定されている場合、OctaneはLaravelに、生成するすべてのリンクにhttps://を先頭に付けるよう指示します。

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

Nginxを使用するアプリケーションの提供

Note: あなた自身のサーバ設定を管理すること、または堅牢なLaravel Octaneアプリケーションを実行するのに必要なさまざまなサービスをすべて設定するのに慣れていない場合は、Laravel Forgeの使用を考慮してください。

本番環境では,NginxやApacheのような伝統的なWebサーバの背後で、Octaneアプリケーションを提供するべきです。そうすることでWebサーバは,画像やスタイルシートなどの静的資産を提供でき,またSSL証明書のターミネーションを管理できます。

下記のNginx設定例では、Nginxはサイトの静的アセットを提供し、ポート8000​​で実行されるOctanサーバへのプロキシリクエストを提供します。

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 Serverが起動するとアプリケーションがメモリにロードされているので、ブラウザを更新してもアプリケーションのファイルの変更は反映されません。たとえば、routes/web.phpファイルに追加されたルート定義は、サーバが再起動されるまで反映されません。利便性を上げるため、アプリケーション内のいずれかのファイルの変更でサーバを自動的に再起動するように、--watchフラグを使用してOctaneへ指示できます。

php artisan octane:start --watch

この機能を使用する前に、Nodeがローカル開発環境内にインストールされていることを確認する必要があります。さらに、プロジェクト内にChokidarファイル監視ライブラリをインストールする必要もあります。

npm install --save-dev chokidar

アプリケーションのconfig/octane.php設定ファイル内のwatch設定オプションを使用して、監視対象のディレクトリとファイルを設定できます。

ワーカ数の指定

Octaneはデフォルトで、マシンの各CPUコアごとにアプリケーションリクエストワーカを起動します。こうしたワーカは、アプリケーションがHTTPリクエストを受信するサーバとして動作します。octane:startコマンドを呼び出すときの--workersオプションにより、いくつの数のワーカをはじめに起動するか指定できます。

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コマンドを使用して、Octaneサーバのアプリケーションワーカを穏やかに再起動することができます。通常、これはデプロイ後に行われ、新しくデプロイしたコードがメモリへロードされ、後続のリクエストから使用されます。

php artisan octane:reload

サーバの停止

octane:stop Artisanコマンドで、Octaneサーバを停止できます。

php artisan octane:stop

サーバ状態の確認

octane:status Artisanコマンドで、Octaneサーバの現在のステータスを確認できます。

php artisan octane:status

依存注入とOctane

Octaneは一度あなたのアプリケーションを起動したら、リクエストを処理しながらメモリに常駐するので、アプリケーション構築中に考慮すべき警告がいくつかあります。たとえば、アプリケーションのサービスプロバイダのregisterbootメソッドは、リクエストワーカが最初に起動したときにのみ実行されます。後続のリクエストでは、同じアプリケーションインスタンスが再利用されます。

このことから、アプリケーションサービスのコンテナやリクエストをオブジェクトのコンストラクタへ注入する際には、特に注意が必要になります。これにより後続のリクエストで、そのオブジェクトはコンテナやリクエストの古いバージョンを持つことになります。

Octaneは、リクエスト間でのファーストパーティフレームワークの状態のリセットを自動的に処理します。しかし、Octaneは、アプリケーションが作成する、グローバルな状態をリセットする方法を常に知っているわけでありません。したがって,どのようにしてあなたのアプリケーションをOctaneに適合するように構築するか認識しておく必要があります。以下では,Octaneを使用する際に問題となる可能性のある最も一般的な状況について説明します。

コンテナ注入

一般的に、アプリケーションサービスコンテナやHTTPリクエストインスタンスを他のオブジェクトのコンストラクタへ注入するのは避けるべきです。たとえば、以下の結合では、アプリケーションサービスコンテナ全体がシングルトンとして結合するオブジェクトへ注入されます。

use App\Service;

/**
 * 全アプリケーションサービスの登録
 *
 * @return void
 */
public function register()
{
    $this->app->singleton(Service::class, function ($app) {
        return new Service($app);
    });
}

この例では、アプリケーションの起動プロセス中にServiceインスタンスが解決されると、コンテナがサービスに注入され、その後のリクエストでも同じコンテナがServiceインスタンスで保持されます。これは、特定のアプリケーションでは問題にならないかもしれませんが、起動サイクルの後半や後続のリクエストで追加される結合を、コンテナが予期せずに見落としてしまう可能性があります。

回避策は、結合をシングルトンとして登録しないか、現在のコンテナインスタンスを常に解決するコンテナリゾルバクロージャをサービスへ注入することです。

use App\Service;
use Illuminate\Container\Container;

$this->app->bind(Service::class, function ($app) {
    return new Service($app);
});

$this->app->singleton(Service::class, function () {
    return new Service(fn () => Container::getInstance());
});

グローバルなappヘルパとContainer::getInstance()メソッドは、常にアプリケーションコンテナの最新バージョンを返します。

リクエストの注入

一般的に、アプリケーションサービスコンテナやHTTPリクエストインスタンスを他のオブジェクトのコンストラクタへ注入するのは避けるべきです。たとえば、以下の結合では、シングルトンとして結合したオブジェクトへリクエストインスタンス全体が注入されます。

use App\Service;

/**
 * 全アプリケーションサービスの登録
 *
 * @return void
 */
public function register()
{
    $this->app->singleton(Service::class, function ($app) {
        return new Service($app['request']);
    });
}

この例では、アプリケーションのプロセス時にServiceインスタンスが解決されると、HTTPリクエストがサービスへ注入され、以降のリクエストでもServiceインスタンスが同じリクエストを保持することになります。したがって、すべてのヘッダ、入力、およびクエリ文字列のデータは、他のすべてのリクエストデータと同様におかしくなります。

回避策は、結合をシングルトンとして登録するのをやめるか、現在のリクエストインスタンスを常に解決するリクエストリゾルバクロージャをサービスへ注入することです。あるいは、最も推奨される方法は、単純に、そのオブジェクトが必要とする特定のリクエスト情報を、実行時にオブジェクトのメソッドの1つへ渡すことです。

use App\Service;

$this->app->bind(Service::class, function ($app) {
    return new Service($app['request']);
});

$this->app->singleton(Service::class, function ($app) {
    return new Service(fn () => $app['request']);
});

// もしくは

$service->method($request->input('name'));

グローバルなrequestヘルパは、常にアプリケーションが現在処理しているリクエストを返すので、アプリケーション内で安全に使用できます。

Warning!! コントローラのメソッドやルートクロージャで、Illuminate\Http\Requestインスタンスをタイプヒントしても構いません。

設定リポジトリ注入

一般的には、設定リポジトリのインスタンスを他のオブジェクトのコンストラクタに注入するのは避けるべきです。たとえば、次の結合は、シングルトンとして結合しているオブジェクトへ設定リポジトリを注入しています。

use App\Service;

/**
 * 全アプリケーションサービスの登録
 *
 * @return void
 */
public function register()
{
    $this->app->singleton(Service::class, function ($app) {
        return new Service($app->make('config'));
    });
}

この例では、リクエスト間で設定値が変更された場合、そのサービスは元のリポジトリインスタンスに依存しているため、新しい値にアクセスできません。

回避策は、結合をシングルトンとして登録するのをやめるか、設定リポジトリのリゾルバクロージャをクラスへ注入することです。

use App\Service;
use Illuminate\Container\Container;

$this->app->bind(Service::class, function ($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;

/**
 * 受信リクエストの処理
 *
 * @param  \Illuminate\Http\Request  $request
 * @return void
 */
public function index(Request $request)
{
    Service::$data[] = Str::random(10);

    // ...
}

アプリケーションを構築する際は、このようなメモリリークを発生させないよう、特に注意する必要があります。ローカル開発時に、アプリケーションのメモリ使用量を監視し、アプリケーションに新たなメモリリークが発生するのを防ぐことを推奨します。

現在のタスク

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の「タスクワーカー」を利用しており、受信リクエストとは全く別のプロセスで実行されます。同時タスクを処理するために利用できるワーカーの数は、octane:startコマンドの--task-workersディレクティブで決めます。

php artisan octane:start --workers=4 --task-workers=6

concurrentlyメソッドを呼び出す場合、Swoole のタスクシステムによる制限のため、1024個以上のタスクを指定してはいけません。

Tickと間隔

Warning!! この機能はSwooleが必要です。

Swooleでは、指定した秒数ごとに実行される"tick"オペレーションが登録できます。"tick"コールバックの登録には、tickメソッドを使用します。tickメソッドの第1引数は、ティッカー(Ticker)の名前を表す文字列を指定します。2番目の引数は、指定した間隔で起動するコールバックを指定します。

以下の例では,10秒ごとに呼び出すクロージャを登録しています。通常tickメソッドは、アプリケーションのサービスプロバイダのbootメソッドの中で呼び出します。

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

immediateメソッドを使用すると,Octaneサーバが最初に起動したときに,直ちにtickコールバックを起動し,その後はN秒ごとに起動するように指示できます。

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

Octaneのキャッシュ

Warning!! この機能はSwooleが必要です。

Swooleを使用する際には、最大200万回/秒の読み取り/書き込み速度を実現するOctaneキャッシュドライバが活用できます。したがって、このキャッシュドライバは、キャッシング層からの極端なリード/ライト速度を必要とするアプリケーションに最適な選択肢です。

このキャッシュドライバは、Swooleテーブルを利用しています。キャッシュに保存したデータは、サーバ上のすべてのワーカが利用できます。ただし、キャッシュされたデータは、サーバが再起動されるとフラッシュされます。

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

Note: Octaneキャッシュで許可するエントリの最大数は,アプリケーションのoctane設定ファイルで定義できます。

キャッシュ間隔

Laravelのキャッシュシステムが提供する典型的な手法に加え、Octaneキャッシュドライバはインターバルベースのキャッシュを備えています。これらのキャッシュは指定された間隔で自動的にリフレッシュされ、アプリケーションのサービスプロバイダでbootメソッド内に登録する必要があります。例えば、以下のキャッシュは5秒ごとにリフレッシュされます。

use Illuminate\Support\Str;

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

テーブル

Warning!! この機能はSwooleが必要です。

Swooleを使用する場合は、任意に独自のSwooleテーブルを定義し、操作できます。Swooleテーブルは、非常に高いパフォーマンスのスループットを提供し、これらのテーブルのデータは、サーバ上のすべてのワーカーからアクセスできます。ただし、サーバを再起動するとテーブル内のデータは失われます。

テーブルは、アプリケーションのoctane設定ファイルのtables設定配列で定義します。テーブルの例として、最大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のテーブルがサポートする、カラムの型はstringintfloatです。

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる