はじめに -課題
インターン先で、とあるアプリケーションを開発していました。
バックエンドはPHP(Laravel)で作成し、ECSにデプロイを行いました。
しかし、APIのリスポンスが全体的にとても遅く、数秒程度かかっていたという問題がありました。これでは大きな問題なので、チューニングを行う必要がありました。初期調査では、AWSのCloudWatchでECSやRDSのメトリクスを確認しましたが、CPU等は余裕があったのでサーバーリソースの問題ではないと判断しました。
また、データベースから多くのデータを取得しないような処理でも時間がかかっており、すぐには原因が分かりませんでした。例えばCloudFront→ECSやECS→RDS間の通信に遅延がかかっている可能性もありますし、PHP自体のパフォーマンスの問題の可能性もあるのでこのままだと原因の切り分けができないという課題がありました。
New Relicの導入
表面的な観測ではパフォーマンスが悪い原因がわからなかったため、New Relicを導入してより具体的な調査を行うことにしました。具体的には、APM機能を利用しLaravel自体のパフォーマンスを見たり、遅いAPIやデータベースクエリを見つけるために使用しました。
APMの確認とopcacheの導入
APMを確認したところ、特段遅いAPIやSQLクエリがある訳ではなかったということがわかりました。しかし、Web transactions timeを確認すると、支配的になっていたPHPの処理時間が1000~2000msかかっていたことがわかりました。
そのため、PHP(Laravel)の性能がボトルネックであると判断し、チューニング方法を探したところ、OPcacheをPHPに導入することで高速化が期待できるということだったので、導入したところ実際に速くなりました。
OPcacheを有効にすると、PHPのスクリプトをコンパイルした後のバイトコードをキャッシュされます。そのため、2回目以降のリクエストで再コンパイルを省略し、高速化を実現できます。
具体的には、DockerfileとPHPの設定ファイルに以下を追加しました。
RUN docker-php-ext-install opcache
[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.validate_timestamps=0
以下の画像を見るとその効果がわかるかと思います。7:50amから8:05amまでの時間で山ができており、PHPのWeb transactions timeが支配的となっており処理に2000ms近く要していることが確認できます。
この時間帯は、OPcacheを外しており、他の時間帯はOPcacheの設定を追加しています。 OPcacheの導入により、PHPの処理時間を1/10近くに減らすことができたということが確認できます。
まとめ
Laravelでアプリケーションを開発する際に、OPcacheの有無ではパフォーマンスに大きな違いが生じることがわかりました。この記事がLaravelのチューニングを図っている方にとって参考になると幸いです。