menu
Webを活用してお客様のビジネス課題を解決します。札幌・東京を拠点にWebコンサルティングをコアにした、Web制作・システム開発・サーバ構築会社です。

Laravelを利用したウェブサイトがCPUピーク時に想定以上にレスポンスが劣化した問題とその対応策

シェア
ツイート
シェア
ブックマーク
タイトルとURLをコピー

最終更新日:2025/06/03   公開日:2025/05/21

はじめに

サービスのリニューアルに際し、Laravelを用いてWebサービスを再構築しました。 このサービスには「毎日特定の時刻に利用が集中する」という特性があるのですが、ローンチ直後、そのピーク時間帯にサイト全体が動作不全に陥る事態が発生しました。 この問題はピーク時のみであり、平時は全く問題になっていません。 原因を調査した結果、アクセス集中によってサーバーのCPU使用率が100%となり、想定以上にレスポンスが遅延していることが分かりました。 

本記事では、この問題が発生した背景、実際に行った対策、そしてその対策を採用する際の注意点について解説します。

Laravel/PHP のボトルネック

Laravelを利用する場合、リクエストごとにフレームワーク全体が初期化されます。この仕組みにより、各リクエストは独立して処理されるため、実行環境が安全性の高いものになっています。これはLaravelに限らず、一般的なPHPアプリケーションでも同様で、リクエスト単位での初期化が基本的な動作となっています。

しかし、この初期化処理には無視できないコストがかかります。今回の環境で初期化にかかる時間を計測したところ、通常時は1リクエストあたり約200msでしたが、CPUがビジー状態にあると1,000~2,000ms程度にまで増加していました。これは通常の5~10倍の遅延に相当します。この初期化遅延はリクエスト単体では小さな問題に見えますが、実際にはピーク時に発生しているため、大量のリクエストが届いており、リクエスト毎にこの応答時間が必要になっています。 大量のリクエストが同時に処理を待つことで、全体のレスポンス速度が著しく低下し、ユーザーにとっては「機能していない」ように見える状況が発生していました。

今回は、AWS環境でvCPUが2個という比較的リソースの少ない構成でした。そのため、並列処理の限界により初期化コストの影響が顕在化しやすかった可能性があります。

対応方法

計測の結果、ボトルネックはフレームワークの初期化処理にあることが分かりました。

たとえばJVM(Java Virtual Machine)のような環境では、初回の初期化には時間がかかるものの、一度初期化された設定やクラスはメモリ上に保持され、その後の処理では再利用されるため、高速に動作するという特徴があります。

Laravelでも同様の仕組みが利用できないか調査したところ、Laravel Octaneというモジュールを導入することで、この「初期化処理の再利用」が可能になることが分かりました。 Laravel Octane は、Swoole や RoadRunner といったアプリケーションサーバーをベースに、リクエスト間でアプリケーションの状態をメモリ上に保持し続ける仕組みを提供します。 これにより、Laravel のブートストラップ処理(初期化処理)を毎回繰り返す必要がなくなり、CPU負荷の軽減とレスポンスの高速化が期待できます。

Laravel Octane 導入時の問題点・注意点

前述の通り、Laravel Octane はアプリケーションの状態をサーバーアプリケーション(Swoole や RoadRunner)上に常駐させ、初期化処理をスキップすることでパフォーマンスを最適化するモジュールです。 その仕組み上、通常のPHP環境(Apache や php-fpm 環境)とは異なる挙動が発生するため、導入に際しては以下の点に注意が必要です。 具体的な違いを以下に示します。

static 変数やミュータブルなシングルトンの扱い

通常の PHP 環境では各リクエストが独立して初期化されるため、static 変数やシングルトンインスタンスはリクエスト単位でリセットされます。しかし、Octane 環境ではメモリがリクエスト間で共有されるため、これらの値が次のリクエストに引き継がれる場合があり、またそのリクエスト順序を制御もできません。状態を保持するような static 変数や、ミュータブル(変更可能)なシングルトンを利用している場合、予期せぬ副作用が発生するリスクがあるため、設計や実装の見直しが必要です。

exit の使用によるアプリケーション終了

Octane のように常駐型で動作するアプリケーションでは、exit を使用するとプロセス全体が終了してしまうため、exit を利用すると致命的な例外として扱われます。 Laravel では、Middleware などでこの例外をキャッチして処理をラップすることで一部の問題を回避できますが、すべての問題を解決できる万能的な解決策ではありません。 特に、既存のコードに exitdie を多用している場合、Octane との互換性に問題が生じやすくなるため、移行時には十分な確認が必要です。

設定ファイルやコードの即時反映が行われない

通常のPHP環境ではリクエストごとに初期化処理が走るため、設定ファイルや .env、キャッシュファイルなどの変更が即時に反映されます。  一方、Octane ではアプリケーションが常駐しているため、起動時に読み込まれた状態が維持され、ファイルの変更が自動的に反映されません。 設定やコードを変更した場合は、Octane サーバーの再起動が必要になります。

このように、通常のPHP環境での運用とは異なる前提となるため、Octane の導入は高負荷対策として有効である一方、システム設計や運用方法にも一定の見直しが必要となる点に留意する必要があります。

結論

Laravel Octane は既存のウェブサーバーを即座に置換できる解決策ではありません。しかし、今回のケースでは、既存アーキテクチャとの相性が良く、大きな問題も発生しなかったため、比較的短期間で Octane への切り替えが可能でした。その結果、リクエストごとの初期化コストを大幅に削減でき、CPU使用率が100%に張り付く事態を回避することができました。

Octane 導入の本質的な目的は「パフォーマンスの向上(特にレスポンス速度の改善)」であり、負荷軽減はあくまでその副次的な効果です。一般的にはLaravel は初期化処理が重く、CPUがビジー状態になると顕著にレスポンスが悪化する場合があります。 そのため、CPU負荷の高騰が予想される環境では、Octane の導入を開発段階から検討することが望ましいです。 また、運用面の柔軟性を確保するために、Apache や PHP-FPMを使う通常版とOctane版の2種類のDockerイメージを用意しておくと、負荷状況や互換性に応じて適切に切り替えることができ、保守性の高い構成になります。