こんにちは。元AI・IoTサービス開発部 から変わり、DXビジネス開発部となりました青木です。
Laravel Octaneなるものをドキュメントで見つけてからいつか手を出そうと思い時間が経ってしましました。 今回はOctaneの導入と、パフォーマンス改善結果などにも触れていきたいと思います。
Laravel Octaneとは
Laravel Octane supercharges your application's performance by serving your application using high-powered application servers, including Open Swoole, Swoole, and RoadRunner.
Open Swoole か RoadRunnerの仕組みの上にLaravelアプリケーションの起動が出来るようになる仕組みです。
今回はOpen Swooleで開発を行ったためOpen Swoole中心に語ります。
従来では PHP-FPM + nginx の構成が一般的でしたが、Open Swooleでは予めプロセスを立ち上げておき、そのプロセスに対して非同期で処理を行う事で高速に処理が出来るようになる仕組みを持っており、リクエスト毎にプロセスを立ち上げていた従来の方法よりも高速に処理することが出来るようになります。
が、従来はプロセスを使い捨てしていた関係上メモリリークなどが起こりづらい状況が作れており、ある意味安全な状態だったもののOpen Swooleに置き換えることでそのあたりも考慮する必要が出てきました。Open Swooleを利用する際に詰まる部分なので注意してください。
Laravel Octaneの導入
既にLaravelでアプリケーションを開発している方も、新規で開発される方も以下のコマンドでサクッと導入出来ます。
composer require laravel/octane php artisan octane:install
開発時は普段通り php artisan serve
で立てられますが、Laravel Octane独自の機能を利用している場合は開発時もOctane経由で起動する必要があります。
php artisan octane:start
このコマンドは、サーバアプリケーションを提供する場合にも利用するコマンドとなります。
php artisan serve
で起動した場合は開発時のみの利用にとどめてください
octane:start
ではローカルにOpenSwooleを入れるなどの対応が必要で少々面倒なのでDockerで実行します。
Laravel OctaneをDockerで実行する
有志の方がご提供頂いているDockerfileを利用してみます。
Dockerfileをプロジェクトルートに入れ以下のコマンドで起動します。
docker build -t octane_test . docker run --name octane_test -p 8000:8000 --env-file .env octane_test
必要に応じてVolumeMountを実施してください
Octaneに変えた効果
良かった点
- レスポンスが早くなった
- リソース消費量が減った
- PHP-FPMとnginxの両方を管理しなくて良くなった
レスポンスが早くなった, リソース消費量が減った
マシンスペックにもよりますが、単純にレスポンスを返却するだけの簡単なエンドポイントであれば概ね 10ms ~ 50ms
程度で返却されるようになりました。
nginx+php-fpmでは同スペックで 100ms ~ 200ms
程度でしたので相当早くなっていることがわかります。
レスポンスが早いこととリソース消費量が減ったのは相関関係にあり、ある程度スペックを絞ってもそれなりのレスポンスを返却してくれるようになりました。
開発のみの環境ですが、k8s上のリソース指定は以下のものでも十分に動作しています。
resources: limits: cpu: 100m memory: 128Mi requests: cpu: 50m memory: 64Mi
PHP-FPMとnginxの両方を管理しなくて良くなった
タイトルの通りで、k8sでも複数のPodやServiceに分かれてデプロイされている関係上リソース管理が2倍になっていたところ、上記記載のDockerImageに変更する事で管理を一つにすることが出来るので便利です。
(nginx ingress を使うことでそのあたりは避けられる可能性もありますが....)
気になった点
- メモリリークしている
メモリリークしている
開発時に利用している閉鎖環境でしばらく様子をうかがっていたところ、メモリーリークを発見しました。 k8sにデプロイしているPodのメモリをDatadogにて集計し、確認をしているのですが画像のように確かにメモリリークされています。
公式ドキュメントでも言及されていますが、普段通りのPHPの使い方を気にせず利用していると意図しないメモリーリークが発生する可能性があります。
こちらのようにLaravelでは非常に利用されるHttpファサードを普通に使うとメモリリークしてしまいます。 今まで普通に利用していたファサードなどを使う場合は簡単にメモリリークされてしまうので要注意です。
GuzzleClientを使うことで解消されるようですが、既存のLaravelサービスをOctaneに変更する等の場合は必ず影響調査を実施した方が良さそうです。
多少のメモリーリークであれば以下の --max-requests
の値を変更するなどしてWorkerの再起動設定を実施すれば通常的に運用する事は可能ですが、
不慮の事故を避けるため解消しておいた方が良いかと思われます。
本件ではHttpファサードを使わないようにしてみたところ以下のようなメトリクスとなり症状は改善されました。
さいごに
Laravel Octane自体は公式ドキュメントにも記載されているようにアプリケーション高速化のデファクトになっていくと思いますので、なるべくキャッチアップしていこうと思います。
オプティムでは、一緒に働く仲間を募集しています。興味のある方は、こちらをご覧ください。