tokuhirom's Blog

Devel::NYTProf で Starlet/Starman (Plack) でうごくウェブアプリケーションのプロファイリングをおこなう方法まとめ

Devel::NYTProf は Perl5 の世界でもっとも人気があるプロファイラである。表示が美麗であるし、ステップごとの処理速度が簡単にわかるのでとても便利だ。

そんな Devel::NYTProf であるが、Starlet/Starman のようなプリフォーク式のサーバーでうごくウェブアプリケーションとくみあわせる場合の方法論として、わかりやすい資料がみあたらなかったのでここに記すものである。

環境変数 NYTPROF を設定する

Devel::NYTProf は環境変数で挙動を変えられる。 plack とくみあわせる場合には、以下のようにするとよい。

NYTPROF=sigexit=int:savesrc=0:start=no

sigexit=int

通常、Devel::NYTProf は END { } ブロックでデータのファイナライズ処理をおこなうのだが、SIGNAL によってプロセスが終了させられた場合はデータがちょちょぎれてしまう。sigexit=int という風に指定すると SIGINT のハンドラを設定して、データのファイナライズ処理をはしらせます。

savesrc=0

Devel::NYTprof はデフォルトではソースを全部 nytprof.out の中にコピーします。これは不要な場合もあるので、不要な場合は savesrc=0 を指定することにより、nytprof.out のデータサイズがちいさくなる気がしています。

start=no

Devel::NYTProf はデフォルトでは読みこまれた時点でプロファイリングがスタートするのですが、Plack のアプリケーションを起動する時点からプロファイラうごかしはじめると、accept や wait3 などの、Starlet の httpd 部分の処理がデータにのってきてしまってワケワカメとなる。

start=no を指定しておくと、NYTProf の処理は起動せず、明示的に起動したタイミングからプロファイラがはしることになる。

stmt=0

上記にはでていないが、おぼえておきたいのがこのオプションだ。これを指定すると、ステートメントレベルでのプロファイリングが無効になるので、爆速になる。本番のサーバーにいれこんだりする場合にはこれをつかうのも有効だろう。

file=/tmp/report/nytprof.out

nytprof.out を出力するパスを変更できる。file の指定をしているときに、fork すると出力ファイルが /tmp/report/nytprof.out.$$ になることに注意していただきたい。

Plack のミドルウェアを指定する

以下のようなシンプルなコードをぶっこんでやればよい。アプリケーションのコードが実行される前にプロファイラを有効にし、おわったら無効にするだけである。

    enable sub {
        my $app = shift;
        sub {
            my $env = shift;
            DB::enable_profile();
            my $res = $app->($env);
            DB::disable_profile();
            return $res;
        };
    };

DB::enable_profile("/tmp/oyoyoo." . $i++); みたいにすれば、任意のファイル名を記入することができる。

データを集計する

nytprofmerge nytprof.out.*
nytprofhtml -m --file=nytprof-merged.out --open

nytprofmerge コマンドにより、nytprof.out.$$ なファイルたちを1ファイルにマージすることが必要だ。特定のファイルだけでいいなら、特定のファイルのぶんだけnytprofhtml しても別によい。

マージしたら、あとは nytprofhtml をかけるだけだ。nytprofhtml --file=nytprof-merged.out を指定して、マージ結果をもとにデータをだすようにする。-m オプションにより、あんまいらないデータをはぶいて、高速にデータをつくります。

まあ、このへんは単純ですね。

まとめ

単純な操作のつみかさねで Starlet/Starman でうごいているアプリケーションのプロファイリングができるということがおわかりいただけたことだろう。

このあたりのコツを体得すれば、パフォーマンスチューニングは怖くない。

P.S.

Plack::Middleware::Profiler::NYTProf はぶっこわれてるそうなので、つかわないのがいいとおもいます。

P.S. (2)

P.S. (3)