CakePHPアプリケーションのパフォーマンスチューニング
-
05-07-2019 - |
質問
この非常に大きなCakePHPアプリ(約2万行のコード)を入手しましたが、あまりきれいではなく、ドキュメントもまったくありません。アプリは運用環境で実行されていますが、パフォーマンスに大きな問題があります。
サーバーは8GB RAMのクアッドコアですが、アプリは約3〜4リクエスト/秒しか処理できません。これは非常に悪いです。各リクエストは、4つすべてのCPUの約20〜30%を使用します。
ab -n 100 -c 10 ...
などの負荷テストを少しでも試してみると、平均応答が7000msになります。ただし、800MB以上のRAMを作成したことがないため、微調整のために少なくとも6GBの空きRAMがあります。
問題は、まだ機能する開発インスタンスを作成できていないため、実稼働環境で調整する必要があることです...
ソースコードを掘り下げずにパフォーマンスを向上させるために簡単に何をお勧めしますか?
解決
ステップ1:Webサーバーではなく、アプリケーションであることを確認します
Cake階層の外部に単純なHello Worldファイルを作成します
<?php
echo 'Hello World';
実行にかかる時間を確認します。サーバー/ネットワークレベルで起こっていることをアプリケーションのせいにするのは簡単です。
test.php
が妥当な時間内にレンダリングされると仮定して、ステップ2に進みます。
ステップ2:すべてをバックアップ
製品コードをいじるのは常に危険なゲームです。開始する前に、修復できないものを破損した場合に備えてデータベースの完全バックアップを行い、ケーキディレクトリツリー全体をコピーします。 1日の作業が終わったら、運用ディレクトリとコピーの内容をdiffします(GUIツールまたはコマンドラインを使用)
diff -r production-cake copy-of-cake
ステップ3:データベースはほとんど常にLAMPスタックの最初のボトルネックです
PHPアプリケーションは、特に人々が実際のSQLクエリの多くを隠すActiveRecordスタイルモデルを使用している場合、多くのSQLクエリを生成します。ファイルやデータベーステーブルへのクエリを記録するようにCakeを設定する必要があります。これを行うには、こちらの指示があります。データベースの代わりにフラットファイルやsyslogにログアウトすることをお勧めします。データベースへのDBリクエストのロギングは、ページの読み込みあたりのクエリ数を2倍にします。
また、IPアドレスからのリクエストのみを記録するようにIPチェックを追加することをお勧めします。そうすれば、ロギングがアプリケーションの通常の実行を劇的に妨げることはありません。
これが設定されたら、1つのリクエストを作成し、生成されているSQLを確認します。パフォーマンスを向上させるためにキャッシュをドロップできる場所として、繰り返し繰り返される同一のクエリを探します。順次クエリも探します
select * from foo where id = 5
select * from foo where id = 6
etc...
舞台裏で何が起こっているのか理解せずに誰かがモデルをループにロードしていることを示します。
ステップ4:データベースでない場合は、システムコールです
データベースがボトルネックではなく、PHP / Apacheが適切に機能している場合、次に探すべきものはシステムコール。シェルアウトは、物事を成し遂げるための迅速で汚い方法ですが、非常に高価な操作です。ループでそれらの1つまたは2つを取得し、完了です。
本番サーバーで top
または ps
を実行し、起動および停止しているプログラムを探して、それらのコマンドのコードベースを検索します。
ステップ4:すべてのコントローラーをコピー
多数のコントローラーを用意します
/app/controllers/posts_controller.php
/app/controllers/other_controller.php
etc...
URLに対応します
http://www.example.com/posts/methodName
http://www.example.com/other/methodName
etc...
特定のリクエストをデバッグしてなぜ遅いかを判断する必要があるときはいつでも、コントローラーのコピーを作成します。
/app/controllers/debugposts_controller.php
そして手動でリクエストを行う
http://www.example.com/debugposts/methodName
その後、コントローラーファイルに必要な数のdebug / printステートメントをスローできます。もしあなたが「幸運」なら、元の開発者はおそらくコントローラーファイルにたくさんのロジックを詰め込んだでしょう。その場合は、「コードの半分をコメントアウト」することができます。ゲーム。
他のヒント
app / config / core.php
でDEBUGレベルを設定して、何が起こっているかを確認できます。欠点は、すべてのユーザーができることです。デバッグをオンにすると、遅いクエリを簡単に確認できます。それがなければ、SQL Slow Query Logをオンにして、カットオフを比較的低く設定します(Cakeは一見単純な質問に答えるために多くのクエリを実行するのが好きだからです)。
少し掘り進むことはないだろうと思う。少なくとも負荷の原因となっているコンポーネントを特定する必要があります。たとえば、インデックス付けが不十分なmySQLテーブルへの大規模なアクセスは、サーバーを本当に狂わせることができます。私の経験では、これがパフォーマンスの問題のよくある理由です。
最も良い方法は、デバッグ/プロファイリング環境をセットアップすることですが、サーバーのプロセスリストを見ると、そのような負荷を引き起こしている人の大まかな概要を把握できます。それは本当にPHPプロセスですか、またはデータベースアクティビティがありますか?
問題は、動作する開発インスタンスをまだ作成できていないことです
これは解決する必要がある問題です。そのアプリをその環境に合わせて実行します(たとえば、すべての環境設定が1つのファイルにあり、そのファイルに環境設定のみが含まれていることを確認します)。これを解決したら、開発中に好きなものすべてをハックできます。