負荷測定
CakePHPベースの自作アプリケーションのα版を公開環境においてみて一番問題だったのは、負荷でした・・・ アクセス〜表示に数秒かかるとは。
アプリ内部の追加や修正が一通り見込みついたところで、負荷対策開始。
手始めとして、実際に負荷を測定して「見える」状態にするために、Benchmarkコンポーネントを入れました。
ApachBenchは、おそらく要ログイン画面の測定ができないので・・・
参考サイト
pblo | ぴーぶろ : webデベロッパーの勉強メモとか
Benchmarkコンポーネントは、以下のものを使用*1
http://blog.aidream.jp/cakephp/cakephp-benchmark-component-1366.html
init.php(bootstrap.phpから読み込んでいるconfig)にベンチマーク実行定数を設定。
app_controller.phpにて、beforeFilter, beforeRender, afterFilterのタイミングで出力するよう設定しました。
任意のアクション表示で、以下のように出力されます。
[cake@cake chara-shee]$ cat app/tmp/logs/debug.log
2010-07-07 12:57:45 Debug: [4ec45881] 0.00001 : <==construct :
2010-07-07 12:57:45 Debug: [4ec45881] 0.15727 : characters/view: beforeFilterStart :
2010-07-07 12:57:45 Debug: [4ec45881] 0.41819 : characters/view: beforeRenderStart :
2010-07-07 12:57:46 Debug: [4ec45881] 0.99297 : characters/view: afterFilterStart :
2010-07-07 12:57:46 Debug: [4ec45881] 1.01849 : <==destruct :
charactersコントローラのviewアクション表示に、約1秒かかっている、という結果がでました。
ちなみに、Apache Benchで同じページの測定結果。
[cake@cake chara-shee]$ ab -n 10 -c 10 http://hogehoge/characters/view/1
(中略)
Requests per second: 1.27 [#/sec] (mean)
大体あってます。
Benchmarkコンポーネント導入差分
--- a/app/config/init.php +++ b/app/config/init.php @@ -39,13 +39,17 @@ Configure::write('Qdmailer', array( 'errorlogFilename' => 'qdmailer_error.log', )); + +/* Benchmarkコンポーネント使用 */ +define('BENCHMARK_MODE', true); --- a/app/controllers/app_controller.php +++ b/app/controllers/app_controller.php @@ -30,10 +30,11 @@ class AppController extends Controller var $components = array( 'AuthPlus', 'Acl', 'Cakeplus.HtmlEscape', 'Token', 'Crypt', 'DebugKit.Toolbar', + 'Benchmark' ); @@ -100,6 +101,8 @@ class AppController extends Controller function beforeFilter() { + $this->Benchmark->report($this->params['controller']. '/'. $this->action . ':' .' b + parent::beforeFilter(); (以下略) +++ b/app/controllers/components/benchmark.php @@ -0,0 +1,54 @@ +<?php +/* + * ベンチマークコンポーネント + * Reffer: http://blog.aidream.jp/cakephp/cakephp-benchmark-component-1366.html + */ + +class BenchmarkComponent extends Object { + var $id = null; + var $start_time = 0; + + //--------------------------------------------------------------------------- + // コンストラクタ + //--------------------------------------------------------------------------- + function __construct() { + $this->id = substr( md5(uniqid(rand(),true)) , 0, 8); + $this->report('<==construct', true); + } + + //--------------------------------------------------------------------------- + // デストラクタ + //--------------------------------------------------------------------------- + function __destruct() { + $this->report('<==destruct'); + } + + //--------------------------------------------------------------------------- + // 計測してログファイルに出力 + //--------------------------------------------------------------------------- + function report($message = null, $reset = false) { + if (defined('BENCHMARK_MODE') === false || BENCHMARK_MODE === false) { + return; + } + if ($reset === true) { + $this->start_time = $this->_getMicroTime(); + } + + $now = $this->_getMicroTime() - $this->start_time; + + $str = sprintf("[%s] %01.5f : %s :", $this->id, $now, $message); + $this->log($str, LOG_DEBUG); + } + + //--------------------------------------------------------------------------- + // マイクロタイムを取得 + //--------------------------------------------------------------------------- + function _getMicrotime() { + if (phpversion() < 5) { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); + } else { + return microtime(true); + } + } +}