Tomcat上のWebアプリケーションをプロファイリングする
Eclipse profilerプラグインでは、別のプロセスに接続してプロファイル情報を取得することが可能になっています。この方法を用いて、TomcatやJBossのようなWebアプリケーションのプロファイルを取得することが可能となります。
■ターゲットプロセスを用意する
まず、ターゲットとなるTomcatプロセスを用意します。前回までの記事でLombozプラグインを使っていますので、ここではそれを利用し、Lombozプラグインによる起動構成を複製して、プロファイリングのリモートターゲットとなる起動構成を作成していきましょう。
Lombozプラグインを使って、ターゲットプロジェクトを以下のように作りました。ソース(search.jsp、result.jsp)はここからダウンロードしてください。
ここでいったんLombozを用いてTomcatサーバを起動すると、起動構成に「プロジェクト名 - ApacheTomcatv410」といったエントリが追加されます。起動したサーバはいまは使わないので終了しておきます。
メニューから[実行(R)]→[実行(N)...]を選択して起動構成ダイアログを表示させ、いま追加された起動構成エントリを右クリックし、[重複]を選んで複製を作り、適切な名前を設定します。新たに作成されたエントリの[引数]タブの[VM 引き数]に、以下の文字列を追加します。
-XrunProfilerDLL:1 -D__PROFILER_USE_PACKAGE_FILTER=1 -D__PROFILER_TIMING_METHOD=1 -D__PROFILER_PACKAGE_FILTER=__M__sun.;__M__com.sun.;__M__java.;__M__javax.;__M__org.apache.
また、プロファイラが利用する以下の3つのjarファイルを、Tomcatのbinディレクトリ(C:\tomcat\bin など)にコピーしておきます(注)。
- ru.nlmk.eclipse.plugins.profiler.ui\profiler_trace.jar
- ru.nlmk.eclipse.plugins.profiler.ui\jakarta-regexp.jar
- ru.nlmk.eclipse.plugins.profiler.ui\commons-lang.jar
注:筆者が試したところ起動構成の[クラスパス]→[ブートストラップクラス]に追加する方法はなぜかうまくいかないようです。
設定後は以下のようになります。
ここまで設定したら、[実行]をクリックしてプロセスを起動しておきましょう(注)。次からの手順で、ここで起動したプロセスに接続してプロファイル情報を収集します。
注:リモートターゲットプロセスは、ポート6743を使用します。このポートを使っている別のプロセスが存在する場合には、うまく起動できませんので、そのプロセスを終了しておく必要があります。
ターゲットとなるTomcatプロセスをコマンドラインから起動したい場合
catalina.batのset JPDA=の次の行に、set JAVA_OPTS=に続けて上記のVM引き数(追加部分)を指定することで、プロファイリングのリモートターゲットとして起動することができるようになります。このとき、libProfilerDLL.dllファイル(またはlibProfileDLL.so)をTomcatを実行しているJREのbinフォルダにコピーしておく必要があります。プラグインのマニュアルに具体的な方法が紹介してありますので、必要に応じて参照してください。
■リモートターゲットに接続する
次に、いま作成したリモートターゲットに接続するための、リモートプロファイラの起動構成を作成します。
まず、メニューの[実行]→[実行...]を選び、起動構成ダイアログを表示します。左ペインの[Remote Profiler]を選択し、その下の「新規」をクリックします。この起動構成には、[Profiler client]とでも名前を付けておきましょう。プロジェクト欄に、ターゲットプロセスが属しているプロジェクトを指定し、Host欄には Tomcatプロセスが動作しているホストを指定します。同じマシンの場合は、「127.0.0.1」を指定しておけばよいでしょう。
そして、この構成で[実行]をクリックすれば、前節「ターゲットプロセスを用意する」で起動したリモートターゲットプロセスに接続してプロファイル情報を取得することができます。
■プロファイル情報を取得している様子
前節「リモートターゲットに接続する」およびその前の節「ターゲットプロセスを用意する」で、それぞれプロファイラ(クライアント)とターゲット(Tomcat)を起動しています。ここで、Profilerパースペクティブに切り替えてみましょう。左上の「デバッグ」ビューに、それぞれのプロセスが表示されているのが分かります。プロファイラプロセスをクリックすると、ターゲットプロセスのプロファイル情報が表示されます。ブラウザから、http://localhost:8080/zip/search.jspというURLでアクセスし、検索したい郵便番号を入力して「Search!」をクリックすると、サーバ側処理が実行され、「郵便番号 [9071801] の 住所は 沖縄県 八重山郡与那国町 与那国 です。」のように結果が表示されます。
このとき、待機していたスレッドが動きだしたことが記録され、「threads」ビューに「Thread-5」のような行が追加されています。この行をクリックしてスレッドの様子を見ると、jspから呼び出している「searchByZip」メソッドがどのように実行されたかを観察することができます(画面10)。
■フィルタを設定しよう
前節ではJSPから呼び出しているクラスをプロファイリングすることはできたのですが、JSP自体のプロファイリングは行えていません。これは、先の設定ではJSPをプロファイリングの対象としていないことが理由です。
-D__PROFILER_PACKAGE_FILTER=で、__M__という接頭辞を付けたパッケージを並べた場合、そのパッケージを除外してプロファイリングします。また、__P__という接頭辞をつけたパッケージを含めると、そのパッケージをプロファイリング対象とします(注)。
ターゲットであるtomcatの起動構成の、「VM引き数」は以下のようになっています。
-D__PROFILER_PACKAGE_FILTER=__M__sun.;__M__com.sun.; __M__java.; __M__javax.;__M__org.apache.
これを下記のように修正することで、JSPをコンパイルした結果のクラスもプロファイル対象に含めることができます。
-D__PROFILER_PACKAGE_FILTER=__M__sun.;__M__com.sun.; __M__java.;__M__javax.; __P__org.apache.jsp.;__M__org.apache.;__P__jp.co.atmarkit.
注:__P__を1つも指定していない場合は__M__にマッチしないクラスはすべてプロファイリング対象となりますが、__P__がひとつ以上ある場合は、前から順に検査していって、いずれかの__P__にマッチしたものだけがプロファイリングの対象となります。
JSPがコンパイルされたら、どのパッケージになる?
Tomcatを用いている場合は、JSPがコンパイルされた結果、org.apache.jspというパッケージに含まれるクラスとなります。webLogicの場合はデフォルトではjsp_servletです(weblogic.xmlでpackagePrefixを再定義できます。関連情報はこちらを参照してください)。JRun4では、無名パッケージになります。WebSphereではTomcatと同様にorg.apache.jspというパッケージになります。
まとめ
Eclipseとプラグインを用いた環境でプロファイリングを行う様子を駆け足でご紹介してきました。商用製品を用いることで、よりきめ細かいプロファイリングを行うことができますが、ある程度のところまではEclipseでも十分なプロファイリングが可能であるといえるでしょう。
プロファイリング、およびその先にあるパフォーマンスチューニングは、とても奥の深い世界です。説明の都合上、小さなサンプルを用いて説明してきましたが、本来、パフォーマンスチューニングという作業は、ソースの一部分を修正するだけでは十分ではないことが多く、場合によってはアーキテクチャを変更する必要が生じることもあります。プロファイリングやチューニングの経験を積み、優れた設計と実装を行うことで、期待される性能を実現できるようになるはずです。
■関連資料
- Java Performance Tuning 邦訳
- J2EE パフォーマンスチューニング徹底解説
- Javaプラットフォームパフォーマンス [邦訳]
- パフォーマンスに関するHints&Tips集 第1版 (EJBコンポーネントに関するコンソーシアム)
- hp-ux Javaパフォーマンスチューニング
- hp-ux performance tuning Java(techniques, tools, and tips)
- @IT連載「[連載] 事例に学ぶWebシステム開発のワンポイント」や「[連載] J2EEパフォーマンスチューニング」
■ボトルネック解析のためのそのほかのツール
ボトルネックを解析できる商用製品として、「JProbe」や「OptimizeIt」、「Wily」といったものがある。ボトルネック解析、メモリリークの抽出、デッドロック/レースコンディションの抽出、テストカバレッジの確認といった作業を容易に行うことができるようになっている。無料で利用できるツールでは以下のようなものがある。
- Extensible Java Profiler
- PerfAnal
- HP JMeter & JTune
- jmp - Java Memory Profiler
- jrat - the Java Runtime Analysis Toolkit
筆者プロフィール
的場 聡弘(まとば あきひろ;matobaa)
現在、株式会社NTTデータ ビジネス開発事業本部に所属。社内技術支援業務に携わり、主にJ2SEおよびJ2EEを用いたシステム構築に係わる方式設計や障害対応を担当している。おちゃらけプログラマ七号機(http://www.ocharake.org/)や、ぱ〜む脱力ゲーム協会(http://palmgames.tripod.co.jp/)の公認脱力作家という顔も持つ。
岡本 隆史(おかもと たかし)
NTTデータ 技術開発本部 所属。Debian GNU/Linuxの優れたメンテナンス性と他のディストリビューションを圧倒するパッケージ数に引かれDebianを使い始めたのをきっかけに、Debian プロジェクトの開発者となりJavaサポートの強化を行う。『Jakartaプロジェクト徹底攻略』(技術評論社)、『WEB+DB PRESS』(技術評論社)、『Java World』(IDGジャパン)、『JAVA Developer』(ソフトバンクパブリッシング)などで執筆活動を行っている。
Copyright © ITmedia, Inc. All Rights Reserved.