シェア
//Laravel Octaneでアプリケーションのパフォーマンスを向上させる

Laravel Octaneでアプリケーションのパフォーマンスを向上させる

Laravel Octane

ご存知の通り、従来のLaravelアプリケーションでは、PHPは1回のリクエストを1回ずつ処理することしかできませんが、Laravel Octaneを使用すると、複数のリクエストを同時に処理できるようになり、ウェブサイトの速度が向上します。

1. Laravel Octaneとは?

Laravel Octaneは、Laravelアプリケーションのパフォーマンスを向上させるために作成されたオープンソースのパッケージです。最初にアプリケーションを1回だけ起動し、それをメモリ(RAM)に保持し、その後のリクエストは、アプリケーションを最初から再起動するのではなく、メモリ内で保存された状態を再利用して処理されます。

Laravelのリクエストライフサイクル

Laravel Octaneのリクエストライフサイクル

Laravel Octaneのもう一つの特徴は、複数のワーカーを同時に使用してリクエストを処理できることです。これにより、以前のようにリクエストを1回ずつ処理するのではなく、複数のリクエストを同時に処理できるようになります。

Sơ đồ xử lý Request trong Laravel Octane

Laravel Octaneのリクエスト処理の概要

Octaneは、FrankenPHP、Swoole、RoadRunnerという3つのPHPの非同期処理ツールを基盤として開発されています。この記事では、Swooleに焦点を当てます。

PHP Swooleは、Erlang、Node.js、Nettyの原則を基にPHP向けに設計されています。しかし、SwooleはLinuxカーネル上でのみ動作するため、現在はLinux、OS X、Cygwin、またはWSLでのみ使用できます。

2. PHP SwooleとPHP-FPMの違い

以下は、PHP SwooleとPHP-FPMの違いを比較した表です。

PHP SwoolePHP-FPM
TCP、UDP、HTTP、HTTP2、Unixソケットのサポートありなし。追加のライブラリが必要
非同期I/Oの使用ありなし
各CPUに対してワーカープロセスの分割 – 同時処理のサポートありなし
PHPファイルをメモリに読み込むありなし
WebSocketサーバーやTCP/UDPサーバーのための長期接続サポートありなし

3. Laravel OctaneとPHP-FPMの速度比較

Laravel Octaneの実力を証明するため、簡単なデモを行い、PHP OctaneとPHP-FPMの結果を比較してみましょう。

次のベンチマークテストを仮想マシン(VMware)で行いました:

テストベンチの統計情報:

  • CPU: 2コア(11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz)
  • RAM: 4GB
  • OS: Centos 7

テストアプリケーション:

  • Laravel 10.10
  • PHP 8.2

ウェブサーバー:

  • PHP-FPM
  • NGINX
  • Laravel Octane

負荷テストツールwrkを使用して、速度をテストします。

(wrkは、ウェブサイトの負荷テストを行うために、多数の同時接続をシミュレートするツールです。)

スレッド数(threads)は4、同時接続数(connections)は100、テストにはLaravelで作成したデフォルトのウェルカムページを使用しました。

Test tốc độ với lệnh wrk Laravel + Nginx + PHP-FPM

Laravel + Nginx + PHP-FPM

Test tốc độ với lệnh wrk Laravel Octane + Nginx

Laravel Octane + Nginx

結果を見ると、Laravel OctaneはPHP-FPMよりも5倍速く、Laravel Octaneは約42リクエスト/秒を処理できますが、PHP-FPMは約8リクエスト/秒です。

以下は、ブラウザを使用した実際のレスポンスタイムのテスト結果です。

b. ワーカの数の指定

Laravel Octaneアプリケーションを起動すると、ワーカの数はサーバのCPUコア数に対応します(例えば、サーバに2コアがある場合、デフォルトで2つのワーカが作成されます)。これらのワーカは、アプリケーションへのHTTPリクエストを処理するために使用されます。

Kiểm tra tiến trình khi start Octane

Octane起動時の進行状況の確認

また、--workersオプションを使って、ワーカの数を手動で指定することもできます。例えば、以下のように指定します。

php artisan octane:start --workers=4

Kiểm tra tiến trình khi start Octane với 6 worker

6ワーカでOctaneを起動したときの進行状況確認

注意点:ワーカの数をサーバのCPUコア数より多く設定すると、リソース競争が発生し、パフォーマンスが低下する可能性があります。したがって、ワーカの数を調整する際は慎重に検討してください。

c. メモリリーク

Octaneは、リクエスト間でアプリケーションをメモリ(RAM)に保持します。そのため、静的オブジェクトにデータを追加すると、メモリリークが発生します。以下の例を見てみましょう:

ルートを routes/web.phpに追加します。

<?php

use App\Http\Controllers\TestMemoryLeakerController;
use Illuminate\Support\Facades\Route;

Route::get('/test', [TestMemoryLeakerController::class, 'test']);

次にファイル App/Services/TestMemoryLeakerService.phpを作成します。

<?php

namespace App\Services;

class TestMemoryLeakerService
{
    // 静的配列オブジェクト
    public static array $staticArray = [];

    // 非静的配列オブジェクト
    public array $array = [];
}

次にファイル App/Http/Controllers/TestMemoryLeakerController.phpを作成します。

<?php

namespace App\Http\Controllers;

use App\Services\TestMemoryLeakerService;
use Illuminate\Support\Str;

class TestMemoryLeakerController extends Controller
{
    public function test()
    {
        // 1MBの文字列データを作成
        TestMemoryLeakerService::$staticArray[] = Str::repeat('a', 1024 * 1024);
        $memoryUsage = memory_get_peak_usage(true) / 1024 / 1024;

        // 結果をddで表示し、ページを更新するとメモリが増加し続けるのがわかります
        dd($memoryUsage . "MB");
    }
}

上記のコードは、1MBのデータを配列に追加することで、静的オブジェクトにデータを追加し、リクエストごとにメモリが増加することを示しています。これが繰り返されることでメモリが溢れてサーバがクラッシュする原因となります。

この問題を解決するために、依存性注入(Dependency Injection)を使用できます。以下のコードを参照してください:

<?php

namespace App\Http\Controllers;

use App\Services\TestMemoryLeakerService;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class TestMemoryLeakerController extends Controller
    {
    public function test(TestMemoryLeakerService $testMemoryLeakerService)
    {
        // 1MBの文字列データを作成
        $testMemoryLeakerService->array[] = Str::repeat('a', 1024 * 1024);
        $memoryUsage = memory_get_peak_usage(true) / 1024 / 1024;

        // 結果をddで表示し、ページを更新してもメモリは変わらない
        dd($memoryUsage . "MB");
    }
}

b. Octane キャッシュ

Swooleを使用する場合、Octaneのキャッシュドライバを使用することができます。このキャッシュドライバは、1秒あたり最大200万の読み書き操作を提供します。したがって、Octaneのキャッシュドライバは、高速な読み書きが必要なアプリケーションに最適な選択肢です。

キャッシュに保存されたデータはサーバ上のすべてのワーカで共有されます。ただし、サーバを再起動するとキャッシュは削除されます。

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class TestCacheController extends Controller
{
    public function test()
    {
        Cache::store('octane')->put('a', Str::repeat('a', 10), 30);
        $a = Cache::store('octane')->get('a');

        dd($a);
    }
}

注意点:Octaneのキャッシュをクリアするために、php artisan cache:clearは使用できません。その代わりに、サーバを再起動することでキャッシュをクリアする必要があります。

c. Octane テーブル

Swooleを使用することで、独自のSwooleテーブルを定義し、操作することができます。これらのSwooleテーブルは、非常に高いパフォーマンスでデータを取得することができ、サーバ上のすべてのワーカがこれらのテーブル内のデータにアクセスできます。

ここでデータは、データベースのテーブルのように行と列で保存されます。まず、config/octane.phpファイルにテーブルを設定する必要があります。以下はその一例です:

<?php
    'tables' => [
        'students:1000' => [
            'fullname' => 'string:1000',
            'class' => 'string:20',
            'created_at' => 'int',
        ],
        'classes:1000' => [
            'class_name' => 'string:1000',
            'class_code' => 'string:20',
            'created_at' => 'int',
        ],
    ],

ここでのstudents:1000は、そのテーブルに格納できる最大行数を示しています。

各行のstring:n、1000および20は、列に格納できる最大のバイト数を示しています。

これらの値を増やしたい場合は、config/octane.phpのキャッシュ設定を編集するだけです。

<?php
    'cache' => [
        'rows' => 1000,
        'bytes' => 10000,
    ],

以下のようにテーブルを操作することもできます:

<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use Laravel\Octane\Facades\Octane;

class TestTableController extends Controller
{
    public function test()
    {
        Octane::table('students')->set('class_monitor', [
            'fullname' => 'Joel Bradley',
            'class' => '12A7',
            'created_at' => Carbon::now()->timestamp,
        ]);

        Octane::table('students')->set('student', [
            'fullname' => 'Reece Bates',
            'class' => '12A7',
            'created_at' => Carbon::now()->timestamp,
        ]);

        $classMonitor = Octane::table('students')->get('class_monitor');
        $student = Octane::table('students')->get('student');

        dd([
            'class_monitor' => $classMonitor,
            'student' => $student,
        ]);
    }
}

出力:

array:2 [
  "class_monitor" => array:3 [
    "fullname" => "Joel Bradley"
    "class" => "12A7"
    "created_at" => 1706549430
  ]
  "student" => array:3 [
    "fullname" => "Reece Bates"
    "class" => "12A7"
    "created_at" => 1706549430
  ]
]

Octaneテーブルを使用する際の注意点:

  • テーブル内のデータは一時的なものであり、サーバ再起動時に失われます。
  • Swooleがサポートする列のデータ型は、stringintfloatです。これはメモリ内に保存される一時的なデータ構造であり、データベースの代わりにはなりません。
  • テーブルに保存されるデータ量が多いほど、使用するメモリ(RAM)が増えます。

d. Ticks & インターバル

Swooleを使用することで、一定の時間ごとに繰り返し操作を実行するTicks機能を使用できます。これはJavaScriptのsetIntervalメソッドに似たものです。

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Laravel\Octane\Facades\Octane;

class AppServiceProvider extends ServiceProvider
{
    /**
     * アプリケーションサービスのブート処理
     */
    public function boot(): void
    {
        Octane::tick('simple-ticker', fn () =>
            var_dump('Ticking...'))->seconds(2);
    }
}

'simple-ticker'はこのタスクの名前であり、fn () => var_dump('Ticking...')は呼び出し可能な関数で、指定された時間ごとに実行されます。
注意:Octaneサーバが動作している間にticksを停止することはできませんので、この機能の使用には注意が必要です。

また、immediateメソッドを使用すると、Octaneサーバが起動したときに即座にticksが呼び出され、その後指定された秒数ごとに再度ticksが呼ばれます:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Laravel\Octane\Facades\Octane;

class AppServiceProvider extends ServiceProvider
{
    /**
     * アプリケーションサービスのブート処理
     */
    public function boot(): void
    {
        Octane::tick('simple-ticker', fn () =>
            var_dump('Ticking...'))->seconds(2)->immediate();
    }
}

7. 結論

Laravel Octaneは、特に並行作業を処理する際にアプリケーションのパフォーマンスを最適化する解決策です。しかし、アプリケーションのライブラリや機能との互換性に注意し、調整が必要です。新しい機能とともに、Laravel OctaneはLaravelアプリケーションの開発において便利で強力なツールとなり、これらの特性を必要とするプロジェクトのパフォーマンスを大幅に向上させることが期待されています。


参照

>>>>> Laravel Octane

>>>>> Free Performance + Extra features for Laravel using Octane and Swoole

>>>>> Laravel Octane: With Great Performance Comes Great Responsibility

あなたのウェブサイトのパフォーマンスを向上させるために以下の記事もご覧ください

>>>>> 非同期および遅延JavaScriptを使用したウェブサイトの速度最適化

Ngụy Minh Tuấn
PHP開発者

今すぐ応募







    福利厚生

    給料・ボーナス制度

    社員の感情・願望を理解しているので、リバークレーンベトナムは特に年2回の定期昇給制度を設けています。毎年6月と12月に評価を行い、毎年1月と7月に給与が変更されます。また、社員は月次と年次の優秀な個人には定期的な業績賞与が別で支給されます。

    日本研修制度

    世界中の新しい技術分野に触れるために、社員を日本にオンサイトさせる方針があります。さらに、技術分野か管理分野かのキャリアパスは社員の決定次第です。

    毎年社員旅行

    リバークレイン・ベトナムは、スタッフに挑戦の機会を提供するだけでなく、年に一度の魅力的な旅行で彼らを楽しませています。エキサイティングなガラディナーやチームビルディングゲームは、リバークレインのメンバー同士の絆をさらに深める手助けをします。

    リバークレイン イベント

    チームビルディング・ファミリーデー・お夏休み・中秋節などのイベントはチーム内のメンバーが接続出来るしお互いに自分のことを共有出来る機会です。ご家族員に連携する際にはそれも誇りに言われています。

    社会保険制度

    リバークレーンベトナムは従業員に社会保険、医療保険、失業手当などの社会保険制度があります。当社は、これらの保険に関するあらゆる手続きをスタッフに必ずサポートしています。さらに、他の保険契約も考慮され、検討されています。

    他福利

    社員向けの活動をサポートすることもあります。 ・文化・芸術・スポーツクラブの運営費用 ・技術研究の教科書を購入する金額 ・エンジニア試験・言語能力試験を受験料 ・ソフトスキルのセミナー・コースの参加費 ・等 また会社政策通り、他のベネフィットもあります。

    © 2012 RiverCrane Vietnam. All rights reserved.

    Close