WebSphere Application Server のパフォーマンス・テストと分析

IBM WebSphere Application Server がサポートするアプリケーションは、増加の一途を辿っています。しかし、それぞれに固有の機能、要件、サービスを持つアプリケーションが、最大の能力を確実に発揮できるようにするためには、アプリケーションごとに適切なパフォーマンス・テストおよび分析を実施する必要があります。この記事では、パフォーマンス・テストを構築して、アプリケーションまたは環境の変化に伴う結果の違いを比較する方法、そして IBM から無料で入手できるツールを使用して、ボトルネックを特定する方法に関するベスト・プラクティスの指針を示します。この記事で説明する方法は、新しくリリースされた WebSphere Application Server V8.5 を含め、すべてのバージョンの WebSphere Application Server に適用できます。

David Hare, Advisory Software Engineer, IBM  

David Hare は、ノースカロライナ州リサーチ・トライアングル・パークにある WebSphere Application Server Performance and Benchmarking 組織の顧問ソフトウェア・エンジニアです。彼が関心を持っているのは、DayTrader パフォーマンス・ベンチマーク、パフォーマンス・チューニング、および新しい Liberty Profile です。



2013年 3月 12日

はじめに

次の状況のうち、思い当たるものはありますか?

  • 現在、パフォーマンス・テストをまったく実施していない。パフォーマンス・テストを実施したいけれども、どこから手を付ければ良いのかもわからない。
  • アプリケーションはこれまで問題なく機能していたが、開発チームが送ってきた更新バージョンをデプロイしてからというもの、サーバーの CPU 使用率が急増している。この CPU 使用率増加の原因は不明である。
  • アプリケーションをバージョン 2.0 から 3.0 にマイグレーションした後、応答時間が 3 倍に増加した。この遅延の原因がわからない。
  • 今後 3 ヵ月のうちに、サポートしなければならないユーザー数が 40% 増えることが見込まれる。クラスターにマシンを単純に追加する以外に、どのような対策があるのかを探している。

これらは、ごく一般的なシナリオですので、心当たりがあるとしても、特別なことではありません。この記事の目標は、このような状況に対処するために、テストの基本的な実施手順と、テストに利用できるツールに関するベスト・プラクティスを提案することです。大まかにまとめると、この記事で取り上げる主なトピックは、次のタスクを行う際に参考になります。

  • 有効なパフォーマンス・テスト・ケースを作成する
  • アプリケーションの利用率を増減させるため、負荷量を変化させる
  • パフォーマンスおよびシステムの主要な評価指標を記録する
  • アプリケーション開発サイクルと並行してパフォーマンス・テストを実施する
  • IBM Health Center などのツールを使用して、パフォーマンスのボトルネックを突き止める
  • 開発チームと協力してボトルネックを修正し、パフォーマンスを再測定する

パフォーマンス・テストの重要性

開発途上のある時点で、パフォーマンス・テストを本番直前に実施する作業として予定したとします。しかし、この場合、実際の問題を特定して修正するには時間が十分ではなく、最小限の作業しか行えないために、結局のところ、本番環境で問題が発覚することも珍しくありません。適切なパフォーマンス・テストを実施するために例外なく推奨される手法は、パフォーマンス・ライフサイクルを実装することです。そして、そのライフサイクルの中で、開発作業の一部としてパフォーマンス・テストをスケジュールし、新しい機能を統合するたびにテストを繰り返すことです。この手法では、すべてを本番に移行する前に、リリース・サイクルに残された十分な時間を利用して、ボトルネックを特定し修正することができます。

適切なパフォーマンス・テストのもう 1 つの利点は、最大限のパフォーマンスを発揮するように、環境 (オペレーティング・システム、JVM、アプリケーション・サーバー、アプリケーション、データベースなど) をチューニングできることです。パラメーターのチューニングは、適切なパフォーマンス・テストを実施してパラメーターを評価し、それらのパラメーターは価値があるかを判断することによって初めて可能になります。ユーザーの多くは開発者の勧めに基づいて JVM ヒープ・サイズだけを設定し、その他の調整は不要とみなして、手を付けることをしません。しかし、驚くかもしれませんが、単純ないくつかのチューニング手順を実行するだけで、チューニング前の環境で必要だったハードウェアの量を半分に削減できる場合もあります。この記事では、この点も検証します

単純なチューニング手順を実行することにより、DayTrader パフォーマンス・ベンチマーク・アプリケーションは、チューニング前の環境の 2 倍以上の負荷に対処できるようになります。これは、利用可能なハードウェア・リソースの半分で、チューニング前と同じ数のユーザーをサポートできるということです。これがどれだけのコスト削減につながるか考えてみてください。

開発サイクル全体にわたりテストを繰り返し実施すること、およびチューニングを目的としたテストの実施による利益に加え、広範なパフォーマンス・テストには、アプリケーションおよび環境の変更に伴う、結果の違いを比較できるという大きな利点もあります。本来のパフォーマンス・テストでは、重要な指標 (後述) が記録されます。この指標により、管理者は発生する可能性のある問題を発見することができます。前述の一般的なシナリオの 1 つでは、多くのユーザーは、アプリケーションを新しいバージョンにマイグレーションしたことによってもたらされた問題の原因を突き止める用意ができていません。その理由は、以前のバージョンで適切なパフォーマンス・テストを実施することも、重要なシステム指標を記録することもしていないためです。記録された指標がなければ、比較の基準として、マイグレーション前のアプリケーション・バージョンを使用してテスト・サーバーをセットアップする必要があるでしょう。システム指標などのデータが用意されていれば、問題の原因がどこにあるのかを、はるかに簡単に分析して発見することができます。


適切なパフォーマンス・テストを実施するためのベスト・プラクティス

適切なパフォーマンス・テストを実施するために欠かせないベスト・プラクティスは、以下の 2 つにまとめることができます。

  • ユーザーの数 (またはクライアント負荷) を変化させること。一般に、本番環境では、アクティブなユーザー数は、1 日を通して変化します。品質テストでは、負荷が低い時でも、ピーク時 (例えば、ブラック・フライデイ) でも、アプリケーションが正常に機能することを確認します。負荷の変化とは、あるリクエストから次のリクエストまでの「思考」時間を変えることや、アプリケーションにアクセスしているアクティブ・ユーザーの数を変えることを意味する場合もあります。品質テストを実施する最善の方法の 1 つは、アクティブ・ユーザーの数を 1、2、4、8 といった具合に変えてテストを実施することです。このテスト方法については、後で具体的に説明します。
  • システムおよびパフォーマンスの重要な指標を記録すること。すべてのシナリオに共通して記録する必要がある、重要な指標がいくつかあります。パフォーマンス・テストを実施するたびに記録しなければならない、最も重要な指標を以下に示します。
    • スループット (1 秒あたりのリクエスト数)
    • 応答時間
    • アプリケーション・サーバー・マシンの CPU 使用率
    • 他のマシンの CPU 使用率 (Web サーバー、負荷ドライバー、データベースなど、該当する場合)

スループットおよび応答時間の指標は、どの負荷生成ツールでも確認することができます。CPU 使用率、メモリー使用量、ディスク入出力、ネットワーク・トラフィックの指標を確認するには、Linux または AIX では vmstat や nmon などのツール、Windows ではタスク・マネージャを使用することができます。上記の指標に加え、システム・レベルのすべての情報を記録することも重要です。この情報には、オペレーティング・システム・レベルの情報、アクティブ・コアの数、使用可能なメモリー (RAM) 容量、「Java バージョン」の出力、WebSphere Application Server のバージョン情報、およびこれまでに適用されたすべてのチューニングが含まれます。これらすべての指標を記録することで、比較対象のシナリオをテストしたのが 2 年前だったとしても、シナリオ同士を簡単に比較することができます。

ほとんどのユーザーは、本番環境を同じサイズのテスト環境で再現できるだけのハードウェアを持っていません。このような場合に推奨される方法は、パフォーマンス・テストのサイズを利用可能なリソースに合わせることです。例えば、本番環境が 10 台の物理マシンで構成されていて、各マシンがそれぞれ 2 つの WebSphere Application Server インスタンスを実行しているとします。この場合、パフォーマンス・テストに使用できる物理マシンが 1 台しかないとしたら、このマシンを本番マシンとできるだけ同じようにセットアップし、パフォーマンス・テストでの負荷を、本番で予期される作業負荷の約 10% にします。そして最終的には、パフォーマンス・テストでの負荷を、完全な本番環境を再現するまで増やします。データベースや LDAP など他のプロセスの負荷をテストする場合にも、これと同じ方法を使用できます。


テスト・ケースと負荷ドライバー

パフォーマンス・テストを実施してアプリケーションのボトルネックを見つける際に、まず最初に必要となるステップは、有用なテスト・ケースを作成することです。テスト結果とその分析の良し悪しは、使用するテスト・ケースの優秀さで決まります。したがって、テスト・ケースを作成するステップを軽視してはいけません。ユーザーが使用時間の 10% に満たない時間しかアクセスしないアプリケーションのコード・パスに負荷をかけても、すべてのユーザーが必ずアクセスするコード・パスに負荷をかける場合と比べて、ほとんど利益はありません。まずは、最もよく使用されるコード・パスを最優先にテストを作成し、その後、使用頻度の低いコード・パスのテストの作成へと移ってください。実際のユーザー・トラフィックをエミュレートする品質テスト・ケースには、必ず十分に時間を費やすことが重要です。この developerWorks 記事は、このパフォーマンス・テスト・ケースの作成を開始する際に、貴重な参考資料となるでしょう。

テスト・ケースの概念を緻密に策定した後、パフォーマンス負荷生成ツールを使用してその概念を実現する必要があります。負荷ドライバーには数多くの選択肢があります。その例としては、IBM Rational Performance Tester と Apache のオープンソース Jmeter があります。この記事では、後者のツールを取り上げます。


DayTrader での例

これまでに developerWorks のパフォーマンス関連の記事を読んだことがあれば、おそらく「Trade」または「DayTrader」ベンチマークについて覚えているでしょう。Apache DayTrader パフォーマンス・ベンチマーク・サンプル・アプリケーションは、単純な株式売買をシミュレートするアプリケーションで、ユーザーはこのアプリケーションにログイン/ログアウトし、自分のポートフォリオの表示、株式情報の検索、株の売買、アカウント情報の管理を行うことができます。DayTrader は、機能テストの実施に最適なアプリケーションであるだけでなく、アプリケーション・サーバーおよびコンポーネント・レベルのパフォーマンスの特性を明らかにし、計測するための、標準的な作業負荷セットを提供します。

DayTrader のベースとなっているのは、Java EE 技術のコア・セットです。具体的には、プレゼンテーション層には Java サーブレットおよび JSP (JavaServer Page)、バックエンドのビジネス・ロジックとパーシスタンス層には JDBC (Java Database Connectivity)、JMS (Java Message Service)、EJB (Enterprise JavaBean)、および MDB (Message-Driven Bean) が使用されています。図 1 に、アプリケーション・アーキテクチャーの概要を示します。

図 1. DayTrader アプリケーションの概要
DayTrader アプリケーションの概要

IBM では、ダウンロード用のサンプル DayTrader パッケージを公開しています。DayTrader アプリケーションおよび必要となるデプロイメント記述子を含むこのパッケージは、WebSphere Application Server V7.0 または以降のリリースにインストールできます。

この記事の例では、DayTrader サンプル・アプリケーションを WebSphere Application Server V8.5 の基本インスタンスにデプロイしました。DayTrader の優れた機能の 1 つは、「Configuration (構成)」タブにある TradeScenarioServlet リンクです。このリンクからアクセスできるサーブレットは、Web ユーザーの集団をエミュレートするために、このサーブレットにアクセスするユーザーそれぞれの特定の操作を無作為に生成します (例えば、あるユーザーは自分のポートフォリオを表示し、別のユーザーは株式の買い上げ操作を実施し、また別のユーザーは株式情報を検索するなどの操作です)。これによって、DayTrader の主要な操作が、テスト中に確実に実行されます。また、操作は無作為に生成されるため、一定の期間が経過すると、各操作はほぼ同じ回数実行されることになります。また、JMeter を使用して、各操作の実行回数と実行順序を正確に指定することができる、非常に複雑なパフォーマンス・テストを作成する方法を説明しているリソースも数多くあります。しかし、この記事の目的を考慮し、テスト・ケースは TradeScenarioServlet を使用した比較的単純なケースに限定することにします。


JMeter を使用する

パフォーマンス・テストを実施するために JMeter をセットアップして実行するには、以下の手順に従います。

  1. JMeter をインストールします。java ディレクトリーを指定して、<JMeter_Home>/bin/ ディレクトリーから jmeter.sh または jmeter.bat スクリプトを使用して JMeter を起動します。JMeter が起動すると、図 2 のようなパネルが表示されるはずです。
    図 2. JMeter のデフォルト・ビュー
    JMeter のデフォルト・ビュー
  2. Test Plan (テスト計画)」を右クリックして、「Add (追加)」 > 「Thread Group (スレッドグループ)」を選択します。ここで、負荷を生成するユーザーの数を定義します。手始めとして、以下の値を使用しましょう (図 3)。
    • スレッド数 (ユーザー数): 1
    • ループ回数: 無限
    図 3. JMeter のスレッドグループのビュー
    JMeter のスレッドグループのビュー
  3. 上記で作成した「Thread Group (スレッドグループ)」を右クリックして、「Add (追加)」 > 「Sampler (設定エレメント)」を選択します。サンプラーでは、生成する負荷のタイプを定義します。サンプラーには、HTTP リクエスト、JMS リクエスト、Web サービス・メッセージなどのタイプがあります。選択可能な各サンプラーの説明については、JMeter のユーザー・マニュアルを参照してください。DayTrader は、Web ベースのトラフィックをサポートしているので、ここでの例では「HTTP Request (HTTP リクエスト初期設定値)」を選択します。ホスト名、ポート、およびパスには、ご使用の環境に応じた値を入力します (図 4)。
    図 4. HTTP リクエスト
    HTTP リクエスト
  4. 作成した HTTP リクエストを右クリックして、「Add (追加)」 > 「Timer (タイマー)」を選択します。タイマーは、リクエストと次のリクエストの間に「思考時間」を追加します。これは、ユーザーがページをクリックした後、そのページの情報を読んでから、次のリクエストを行うという操作をシミュレートするためです。タイマーには、単純な一定時間のタイマーから複雑なガウスやポアソン分布タイマーまで、事前定義された選択肢が多数あります。選択可能な各タイマーの説明については、JMeter のユーザー・マニュアルを参照してください。この単純な例では、5 ミリ秒の「Constant Timer (定数タイマー)」を使用します。
  5. Right click on the thread group and go to Add > Listener > Summary Report. This will show you the response times and throughput results while the test is running.
  6. 設定をファイルに保存して、後で再度ロードできるようにしておいてください。

テストを実行する

負荷生成ツールを起動する前に、必ずブラウザーでアプリケーションが機能していることを確認してください。準備ができたら、緑色の矢印をクリックするか、「Run (実行)」 > 「Start (開始)」の順にクリックします。これで、JMeter はクライアントから指定されたサーバー・パスにリクエストを送信し、5 ミリ秒待機してから次のリクエストを送信するという操作を繰り返します。「Summary Report (統計レポート)」をクリックすると、テスト実行中に結果を表示することができます。

スループットが、次第に増加していく期間があることに気付くはずです。この期間は、「ウォームアップ」期間と呼ばれます。JRE がすべてのクラスに負荷をかけて、JIT に何らかの最適化を行わせるまでには、一定のウォームアップ期間が必要です。最終的にスループットは安定し、一定の数値に落ち着きます (1 秒あたりのリクエスト数の違いがわずかになります)。テストの複雑さによって、このウォームアップ期間は 30 秒のことも、30 分のこともあります。

テストの実行中に、ターミナルを開いて (Linux または AIX の場合)、vmstat 5 を実行し、5 秒間隔でシステム指標が表示されるようにします (リスト 1)。

リスト 1
[root@spice3 bin]# vmstat 5 
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- 
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st 
 0  0      0 8235164 104920 500956    0    0    13    11   44  154  8  5 86  0  0 
 0  0      0 8235164 104928 500956    0    0     0     3 8030 4987  6  1 93  0  0 
 1  0      0 8235040 104936 500956    0    0     0     3 7982 4944  5  1 94  0  0 
 0  0      0 8233116 104936 500960    0    0     0     6 8126 5020  7  1 92  0  0 
 0  0      0 8231068 104944 500960    0    0     0     6 7952 4939  6  1 93  0  0 
 0  0      0 8231316 104952 500960    0    0     0     3 7761 4819  5  1 94  0  0 
Example vmstat output showing ~7% CPU utilization.

Windowsを使用している場合は、タスクバーを右クリックし、「タスク マネージャ」を選択して「パフォーマンス」タブを選択します。JMeter のスループットが一定値に落ち着くのを待ってから、WebSphere Application Server が実行されているサーバーおよびその他該当するサーバーにおける CPU 使用率を記録します。記録が完了したら、赤い停止記号をクリックするか、「Run (実行)」 > 「Stop (停止)」の順にクリックして JMeter テストを停止します。すると、図 5 のような JMeter の要約レポートのビューが表示されます。

図 5. JMeter の統計レポートのビュー
JMeter の統計レポートのビュー

スプレッドシートに、スループットの結果 (93.9 リクエスト/秒) と平均応答時間の結果 (4 ミリ秒) を記録してください。さらに詳細な情報が必要な場合には、「Min (最小)」、「Max (最大)」、「Std. Dev. (標準偏差)」応答時間の結果も記録しておくと役に立つはずです。

すべての結果を記録したら、「Run (実行)」 > 「Clear (消去)」を選択して、要約レポートの結果をクリアします。これで、単一ユーザーに対するテストは完了です。あとは、ユーザー数を 2、4、8 といった具合に増やして、上記の手順を繰り返します。ユーザー数を増やすにつれ、スループットが増加していくことがわかるはずです。最終的にはスループットの増加が止まり、さらには減少する場合もあります。スループットが安定状態に達したら (あるいは悪化してきたら)、テストを停止して構いません。


結果を分析する

前のセクションで説明したテスト手順を完了すると、図 6 のような内容のスプレッドシートが出来上がっているはずです (これらのテスト結果は、DayTrader アプリケーションと、テストを実行した環境に大きく依存するため、皆さんの結果は、これとはかなり異なるでしょう)。

図 6. テスト結果 - 表形式
テスト結果 - 表形式

生データを上記のような表形式にすると、大変に便利であるだけでなく、結果をグラフ形式で表示する際にも役立ちます。データを視覚化するのに最適な手段の 1 つは、XY 散布図を使用することです。グラフを作成して結果を視覚化すると、その傾向を簡単に識別することができます。図 7 のグラフは、クライアント数に対する、スループットおよび WebSphere Application Server の CPU 使用率を示しています。

図 7. テスト結果 - グラフ形式
テスト結果 - グラフ形式

上記の図 7 には、興味深い特徴がいくつか示されています。第一に、スループットの曲線と CPU 使用率の曲線がほとんど一致しています。第二に、アプリケーションのスループットは、クライアント数が 1 から 500 までの間は線形に増加しています。ここまでは理想的な結果ですが、クライアント数が 500 から 1,000 の間のある時点で、スループットの増加が鈍くなります (この減速が発生するポイントを正確に突き止めるために、クライアント数が 500 から 1,000 の間のユーザー負荷で、さらにテストを実施することもできます)。クライアント数が 1,000 を越えてさらにクライアント負荷が増加すると、アプリケーション全体のスループットは改善しなくなります。これは、飽和点と呼ばれ、パフォーマンス・テスト中に必ず見つけなければならない重要な値です。この飽和点は、アプリケーション、チューニング、構成、および環境が発揮できる最高の能力を示しています。飽和点を超える数のユーザーを追加しても、クライアント応答時間が増加するだけで、アプリケーション全体のスループットは改善されません。飽和点を上回るパフォーマンスを達成するには、アプリケーション・コードの変更、チューニングの変更、または環境の変更が必要になります。

DayTrader と皆さんのアプリケーションの違い

DayTrader は、すべてのアプリケーションを代表しているわけではありません。皆さんのアプリケーションは、この例よりもずっと早い段階で飽和点に達するかもしれません。この場合、アプリケーションのボトルネックを示唆している可能性があります。このボトルネックを修正するためには、アプリケーション分析が必要となります。

このようなタイプのテストと分析は、サイズおよびキャパシティ・プランニングを検討する際に、極めて重要です。本番環境をサポートするために必要な総キャパシティを正確に見積もる唯一の手段は、飽和点を特定することです。例えば、「この環境では、ユーザー数 10,000 をサポートする必要がある」という前提条件の下、クライアント負荷を発生させて、パフォーマンス・テストを実行することがよくあります。しかし、この手法では、WebSphere Application Server または他のインフラストラクチャーの構成要素 (ネットワークやデータベースなど) の 1 つ以上のコンポーネントで、さまざまな過負荷状態が発生することになります。それよりも生産的な手法は、1 台のアプリケーション・サーバーで対処可能なクライアント負荷および達成可能なスループットを見極めてから、これらの値を基にしてランタイムとアプリケーションのチューニングを行うことです。このチューニングを完了した後で、スケーラビリティー要件を満たすために必要となるアプリケーション・サーバー・プロセスの数と、物理サーバーの数を決定する作業に取り組むことができるようになります。

JMeter に、飽和点として判明したスレッド数 (ユーザー数) を設定した新しいテストを保存してください。アプリケーションや環境を変更した時に、このテストを実行すれば、スケーラビリティー・テスト全体を繰り返すことなく、迅速にパフォーマンスを比較することができます。もちろん、スケーラビリティー・テストが不要になると言っているわけではありません。そうではなく、変更を行った時に、飽和点の負荷でテストを実行すれば、それよりも負荷が低く、CPU がフルに活用されない場合には現れない違いが明らかになりやすいと言っているのです。アプリケーションやチューニングに小規模の変更を行った場合には、飽和点の負荷でテストを実行し、大幅な変更を行った場合には、完全なスケーラビリティー・テストを繰り返すことが、グッド・プラクティスです。


パフォーマンス・ツール

ここまでのセクションは、実際の分析作業を実施するための前提条件でした。ボトルネックとパフォーマンスの改善点を探すためには、その前に、再現可能なパフォーマンス結果を生成する方法を理解しておくことが必要だからです。その方法を理解したところで、ここからはパフォーマンスの改善点を探す作業に取り掛かりますが、その分析に使用する、2 つのパフォーマンス・ツールを以下に示します。

  • IBM Tivoli Performance Viewer

    Tivoli Performance Viewer (管理コンソール内) は、WebSphere Application Server をモニターする際に大変に役立つツールです。この記事では、環境を最適にチューニングするために Tivoli Performance Viewer を使用すると、いかに大きなメリットがあるかを明らかにします。同じく、Tivoli Performance Viewer を使用すると、チューニングによって簡単に除去できるボトルネックがあるかどうかを簡単に見つけることもできます。

    Tivoli Performance Viewer は、以下の単純な手順で開始できます。

    1. 飽和点として特定されたユーザー数を指定して、JMeter の負荷を再開します。
    2. 管理コンソールにログインし、「Monitoring and Tuning (モニターおよびチューニング)」 > 「Performance Viewer (パフォーマンス・ビューアー)」 > 「Current Activity (現在のアクティビティー)」を選択します。モニター対象のサーバーをクリックし、「Performance Modules (パフォーマンス・モジュール)」を展開します。これで、表示可能なパフォーマンス・モジュールのリストが表示されます。
    3. これらのモジュールのうち、どのモジュールを表示すると最も有益かは、アプリケーションの特性によって決まります。この DayTrader サンプルのように Web ベースのトラフィックの場合には、まず初めに「Thread Pools (スレッド・プール)」 > 「WebContainer」 モジュールを表示してください。このモジュールのチェック・ボックスにチェック・マークを付けた後、上部にある「View Module (モジュールの表示)」ボタンをクリックすると、図 8 のようなグラフが表示されます。JMeter テストの実行中、このグラフには 30 秒ごとに自動的にデータが追加されていきます。
      図 8. WebContainer PMI データ
      WebContainer PMI データ

      この例では、WebContainer スレッド・プールのサイズが 50 に設定されている一方で、使用中のスレッドは約 32 であることが示されています。したがって、現在の作業負荷では、WebContainer スレッド・プール・サイズはボトルネックではないことがわかります。アクティブ・カウントが 45 から 50 の間で変動している場合は、WebContainer スレッド・プール・サイズがボトルネックである可能性があります。その場合は、WebContainer スレッド・プール・サイズを増やしてテストを繰り返し、パフォーマンスが改善されるかどうかを調べます。スループットが増加する場合は、完全なスケーラビリティー・テストを再実行して、ベースラインを再設定する必要があります。

    4. アプリケーションに適用可能な他のモジュールを使用して、ステップ 3 を繰り返します。DayTrader のようなトランザクション・アプリケーションの場合、他に確認する必要があるモジュールは、JDBC Connection Pools 情報です。「JDBC Connection Pools (JDBC 接続プール)」 > (使用している JDBC ドライバー) を展開し、使用しているデータソース JNDI 名を選択します。「View Module (モジュールの表示)」ボタンをクリックすると、図 9 のようなグラフが表示されます。
      図 9. DataSource PMI データ
      DataSource PMI データ

      このグラフには、デフォルトで選択されている項目以外にも、いくつかの異なるオプションが表示されています。PoolSize、FreePoolSize、および WaitingThreadCount はいずれも極めて役立つ指標であり、接続プールが競合の原因になっていないことや、WebContainer スレッドがデータベース接続のために待ち行列を作っていないことを確認することができます。上記の例では、接続プール・サイズは接続数 50 に固定されています (これは、チューニング設定です)。空きプール・サイズは 20 前後で変動しているので、同時にアクティブになっている接続数は約 30 ということになります。これらの事実からわかることは、WaitingThreadCount は 0 ということです。つまり、データベースへの接続を待機しているスレッドはありません。これで、JDBC 接続プールのサイズが、ボトルネックでないことは確実です。空きプール・サイズが 0 で、待機中のスレッド数が 0 よりも大きい場合には、接続プールのサイズを大きくしてテストを繰り返す必要があります。

    上記のプロセスを、アプリケーションのモニターに役立つ、その他のパフォーマンス・モジュールで繰り返します。モニターする価値のある統計については、「The WebSphere Contrarian: Preparing for failure」に包括的なリストが記載されています。この演習が完了したら、次は IBM Health Center でさらに詳細に分析することができます。
  • IBM Monitoring and Diagnostic Tools for Java - Health Center

    IBM Monitoring and Diagnostic Tools for Java - Health Center (以降、Health Center と略称します。これは、IBM Support Assistant の一部です) ツールは、WebSphere Application Server プロセスに関する詳細なパフォーマンス分析用に推奨されているツールです。Health Center は、サーバーのパフォーマンスに関する豊富な情報を提供します。その情報を以下に挙げます。

    • メモリー使用率
    • ガーベッジ・コレクション統計
    • メソッド・レベルのプロファイリング
    • ロック競合分析

    Health Center がツールとして統合されている ISA (IBM Support Assistant) は、無料でダウンロードすることができます。ISA のインストール先は、必ずアプリケーション・サーバー・マシンとは別のマシンにしてください。同じマシンにインストールすると、Health Center がアプリケーション・サーバー・プロセスからリソースを奪ってしまうため、正確な結果にならない場合があるからです。Health Center は対話モードで実行することも、情報を後で確認できるようにファイルに保存する「ヘッドレス」モードで実行することもできます。この例では、対話モードを使用します。

    以下の手順に従って、Health Center を起動してください。

    1. 汎用 JVM 引数 -Xhealthcenter を指定して、詳細情報の収集対象である WebSphere Application Server プロセスを再起動します。
    2. ISA を起動します。ロードが完了したら、「Analyze Problem (問題分析)」を選択します (初めて実行する場合は、WebSphere Application Server 用のツールを対象としていることを ISA に指示する必要があります)。
    3. IBM Monitoring and Diagnostic Tools for Java - Health Center」を選択し、「Launch (起動)」をクリックします (図 10)。
      図 10. ISA から Health Center を起動する
      ISA から Health Center を起動する
    4. 接続ウィザードが表示されたら、「Next (次へ)」をクリックします。アプリケーション・サーバーが稼働しているマシンのホスト名または IP アドレスを指定します。デフォルトでは、ポート 1972 が使用されますが、セキュリティー要件により別のポートを使用する必要がある場合は、そのポート番号を指定します。その必要がなければ、「Next (次へ)」をクリックしてください。ホスト名とポートが見つかったら、再び「Next (次へ)」をクリックします。見つからない場合には、接続できない理由を調べる必要があります。接続に成功すると、図 11 のような Health Center のビューが表示されます。
      図 11. Health Center のデフォルト・ビュー
      Health Center のデフォルト・ビュー
    5. Health Center の画面を最大化し、さまざまなリンクをクリックして機能の概要を把握しましょう。これで、詳細なパフォーマンス分析を開始する準備が整いました (次のセクションで詳しく説明します)。飽和点として特定されたユーザー数で JMeter の負荷を再開してください。新しい情報を入手するごとに、Health Center は動的に更新されます。ウォームアップ期間が完了するまで JMeter で負荷の生成を続けて、次の作業に備えてください。

ガーベッジ・コレクション分析

Java アプリケーションのパフォーマンス分析は、常にガーベッジ・コレクション統計の調査から始まります。Health Center が稼働中であれば、このステップは非常に簡単に実施できます。

Health Center ウィンドウで、「Garbage Collection (ガーベッジ・コレクション)」リンクをクリックします。図 12 のようなビューが表示されます。

図 12. Health Center - ガーベッジ・コレクションのビュー
Health Center - ガーベッジ・コレクションのビュー

初歩的なレベルの分析のために、最初に検討する必要がある重要な 2 つの点を以下に示します。

  • 左下隅の「Analysis and Recommendations」セクションには、Health Center に組み込まれたインテリジェンスに基づいた有用なヒントと情報が提供されます。このヒントが示すのは、推奨されるガーベッジ・コレクション・ポリシーやヒープ・サイズ、およびメモリー・リークや System.gc() 呼び出しに関する計測結果などです。図 12 のこのセクションで示されている内容は、DayTrader には gencon が最適な GC ポリシーであること、およびアプリケーションにはメモリー・リークが認められないことです。このセクションは常に、優れた出発点です。
  • ウィンドウの下部にある「Summary」パネルには、関心を払う必要がある最も重要な統計データが記載されます。その 1 つは、「Proportion of time spent in Garbage Collection pauses (ガーベッジ・コレクションの休止に費やされた時間の比率(%))」です。この 1 つの統計データだけで、ガーベッジ・コレクションの発生によってアプリケーションが停止した時間の割合がわかります。この数値は可能なかぎり小さくしなければなりません。理想的には、2% から 3% に抑えたいところです。例えば、この数値が 10% の場合、JVM ヒープ・サイズとガーベッジ・コレクション・ポリシーの最適なチューニングによって、スループットを最大 10% まで改善できる可能性があります。前述のパフォーマンス関連の developerWorks 記事に、ケース・スタディーでこのチューニング・プロセスの手順をわかりやすく解説している記事があるので参照してください。

役立つデータを見つけるには、以下のヒントも参考になります。

  • 図 12 のグラフでは、X 軸がサーバー起動後の経過時間を示していますが、この経過時間を時刻に変更してグラフ化することもできます。これは、発生したアクティビティーと 1 日の特定の時刻とを関連付ける場合に役立ちます。X 軸を変更するには、コンテキスト・メニューから「Change Units (単位の変更)」 > 「X-Axis (X 軸)」 > 「Time (時刻)」を選択します。
  • データをトリミングしてウォームアップ期間を除外すると、通常のアクティブな状態での動作をより明確に把握することができます。そのためには、「Data (データ)」 > 「Crop Data (データの切り取り)」を選択するか (開始部分と終了部分をトリミングする場合)、「Data (データ)」 > 「Reset Data (データのリセット)」を選択して、現時点までのデータをすべてクリアします。
  • さらに詳細に分析するには、「Samples by object」タブをクリックします。このタブでは、割り当てられているオブジェクト名、各タイプの割当数、および合計サイズの内訳を確認することができます。また、パッケージごと、あるいはオブジェクト名ごとに検索するオプションもあります。その一例を図 13 に示します。これらの結果を基に、アプリケーション・コードを検討して BigDecimal および BigInteger の使用を減らすことができるか調べることも得策です。
図 13. Health Center - オブジェクトごとのサンプルのビュー
Health Center - オブジェクトごとのサンプルのビュー

メソッドのプロファイリングによる分析

負荷ドライバーが実行中の状態で、「Profiling (プロファイル作成)」リンクをクリックします。図 14 のような「Method Profile」ビューが表示されます。

図 14. Health Center - Method Profileのビュー
Health Center - Method Profileのビュー

「Method Profile」表からは、最も処理リソースを使用しているメソッドを把握することができます。これは JVM 全体のビューであり、特定のアプリケーションのビューではありません。したがって、このビューにはデータベース・ドライバーや WebSphere Application Server コンテナーなどに関するメソッド情報が示されます。このビューを調べると、サーバーで何が行われているのかについて、その全容をつかむことができます。ガーベッジ・コレクション分析のセクションと同じように、分析の出発点としてまず初めに確認すべきセクションは、「Analysis and Recommendations」です。このパネルには、CPU サイクルを最も消費していることが判明したメソッドが示されます。上記の例では、サイクル全体がかなり均一に分配されているため、最適化候補として明らかになったメソッドはないことを通知しています。このセクションに 1 つか 2 つのメソッドが示されている場合には、そのメソッドのコードを検討して、最適化が可能かどうか、あるいはそのメソッドを呼び出す回数を減らせるかどうかを調べてください。

さらに深く掘り下げるには、表内のデータの解釈方法を理解する必要があります。この表の意味を理解するには、「Help (ヘルプ)」 > 「Help Contents (目次)」の順に選択し、「Tool: IBM Monitoring and Diagnostic Tools for Java - Health Center」までスクロールダウンして、このマニュアルを展開してください。マニュアルでは、以下のように説明しています。

Self(自己) (%) 値が高いメソッドは「ホット」と評され、最適化の有力候補です。このメソッドの効率性を少し改善するだけで、パフォーマンスに大きな効果が現れることもあります。メソッドを最適化するには、そのメソッドの作業量を減らすか、メソッドの呼び出し回数を減らします。表の終わり近くにあるメソッドは、最適化の対象にはなりません。というのは、これらのメソッドはそれほど多くの処理リソースを使用するわけではないので、メソッドの効率性を大幅に改善しても、パフォーマンスに対する効果は期待できないからです。

以下に、表の各列について説明します。

表 1. Method Profile表
説明
Self(自己) (%)そのメソッドが、スタックの先頭で実行されている間に、取得されたサンプルの割合。この値により、処理リソースの使用という点で、そのメソッドのコストがどのくらい高いかがわかります。
Self(自己)Self(自己)(%) 列のグラフ表示。バーの幅が広く、赤が濃くなるほど、ホットなメソッドです。
Tree (ツリー)(%)そのメソッドが、コール・スタックのどこかに含まれている間に、取得されたサンプルの割合。この値は、そのメソッドと、そのメソッドが呼び出した下位の子メソッドに費やされた時間の割合を示します。この値は、アプリケーションで最も処理時間が掛かっている部分を知る目安となります。
Tree(ツリー)Tree(ツリー) (%) 列のグラフ表示。バーの幅が広く、赤が濃くなるほど、ホットなメソッド・スタックです。
Samples(サンプル)そのメソッドが、スタックの先頭で実行されている間に、取得されたサンプルの数。
Method(メソッド)完全修飾されたメソッド表現であり、パッケージ名、クラス名、メソッド名、引数、および戻り値の型を含みます。

これらの列のいずれかをソートするためには、その列のヘッダーをクリックして、昇順または降順でソートします。以上の点を理解していれば、作業負荷のパフォーマンス特性を堀り下げていくことができます。表をナビゲートする際に役立つヒントをいくつか示します。

  • 表の行をクリックすると、パネルの下部に、そのメソッドがどのように実行されたのかを示す、完全な呼び出しパスが表示されます。
  • Timeline」タブには、プロファイリングがアクティブになっている間のどの時点でメソッドが実行されたのかが示されます。これにより、プロファイルのその時点より前の実行内容 (おそらくウォームアップ期間) ではなく、それ以降の実行内容に焦点を絞ることができます。
  • Filter methods」テキスト・ボックスは、特定のクラスを検索し、プロファイルの残りのクラスを除外するのに役立ちます。対象のアプリケーションの詳細だけをドリルダウンし、他のアプリケーションのクラスを除外するには、このフィルタリング機能を使用してください。一例として、DayTrader アプリケーションのすべてのクラスには、パッケージ名に「daytrader」という文字列が含まれているため、「daytrader」でフィルタリングしたプロファイルを図 15 に示します。これにより、これらのアプリケーションだけを対象にして、最もリソースを使用しているメソッドを調べることができます。
図 15. DayTrader でフィルタリングしたMethod Profileのビュー
DayTrader でフィルタリングしたMethod Profileのビュー

アプリケーションの特定のメソッドが、CPU サイクルを大量に消費している場合、Health Center は「Analysis and Recommendations (分析および推奨案)」パネルで、最適化の有力候補としてそのメソッドにフラグを立てます。図 16 に、その一例を示します。

図 16. 最適化候補の例
最適化候補の例

Method Profileは、アプリケーションのパフォーマンスの改善点を発見するために、何日にもわたって分析されることがあります。しかし、出力はファイルに保存できるので、アプリケーションの変化をごく簡単に比較することができます。アプリケーション開発者が変更を加えたアプリケーションをデプロイし、Health Center で負荷テストを行えば、変更後のプロファイル情報を、変更前のプロファイル情報と比較して、開発者が変更したメソッドによって処理要件が増加したか、減少したかを調べることができます。


ロックの分析

マルチスレッド・アプリケーションでは、共有リソースを同期 (またはロック) して、リソースの一貫性を維持する必要があります。この一貫性により、あるスレッドの状態が、別のスレッドの読み取り中に変更されることがなくなります。

多数のプロセッサーを搭載したシステムにデプロイされた、高負荷のアプリケーションでロックを使用する場合、ロック操作によって、アプリケーションが使用可能なリソースをすべて使用してしまうことを防ぐことができます。例えば、8 コア搭載のマシンで実行されているアプリケーションで、重要なアプリケーション・コード・パスが一度に 1 つのスレッドしか実行できないように、強く同期されている場合を考えてみてください。この場合、他の 7 つのスレッドは待機中のままになります。

4 コア以上のマルチコア・マシンでアプリケーションを実行する際に、アプリケーションをスケールアップして、使用可能なすべてのハードウェア・リソースを使用できるようにするためには、ロック分析が不可欠です (その一方で、アプリケーションをシングル・コア・マシンで実行している場合は、ロック分析にそれほどの価値はありません)。「Locking (ロック)」パースペクティブにより、ロック使用率がプロファイリングされ、アプリケーションまたは Java ランタイムにおいて、アプリケーションの拡張を妨げている競合箇所を特定することができます。「Locking (ロック)」リンクをクリックすると、図 17 のようなパネルが表示されます。

図 17. Health Center - ロックのビュー
Health Center - ロックのビュー

一見するところ、「Monitors bar chart」ビューは難解な印象を与えるかもしれませんが、Health Center マニュアルでは、このパネルの指標を理解できるように、極めて詳細に説明しています。表 2 に、表の列の内容について説明します。

表 2. モニター
説明
% miss(取得失敗(%))Gets (取得) の総数のうち、同期されたコードのロックを要求するスレッドが、ロックを取得するまでブロック状態となった割合。
Gets(取得)モニター使用中にロックを獲得した総数。
Slow(低速)ロックが別のスレッドによって所有されていたために、要求側スレッドが待機しなければならなかった、非再帰的ロック獲得の総数。
Recursive(再帰的)再帰的獲得の総数。再帰的獲得は、要求側スレッドがすでにモニターを所有している場合に発生します。
% util(使用率(%))ロック保持時間を出力に費やされた時間で割った割合。
Average hold time(平均保持時間)スレッドごとの平均ロック保持 (所有) 時間。例えば、プロセッサー・クロックのティック数で測定した、同期されたブロックで費やされた時間。
Name(名前)モニターの名前。名前が不明の場合は、この列はブランクとなります。

この表には、使用されたすべての Java モニターがリストされます。最初に注目される列は、% miss (取得失敗(%))です。この率が高い場合、ロックで保護された同期リソースで頻繁に競合が発生していることを意味します。この競合により、Java アプリケーションの拡張が妨げられている可能性があります。

ロックの % miss (取得失敗(%))が高い場合には、Average hold time(平均保持時間) と % util (使用率(%))を調べてください。以下に、ヒントをいくつか挙げます。

  • % util (使用率(%))が高く、Average hold time (平均保持時間)も長い場合は、ロックの保持中に実行される作業量を減らす必要があるかもしれません。
  • % util (使用率(%))が高く、Average hold time (平均保持時間)が短い場合には、ロックで保護されるリソースをより細分化して、ロックを複数のロックに分割する必要があるかもしれません。

まとめ

適切なツールと正しい知識がなければ、パフォーマンス・テストと分析を開始するのは難しいかもしれません。しかし、この記事で説明したように、いくつかの簡潔なステップに従って、正しいパフォーマンス・テストを実施すると、アプリケーションのボトルネックは取り除かれ、可能なかぎり効率的に動作するようになります。

もし、皆さんのアプリケーションが、DayTrader とは似ていないとしても、パフォーマンス・テストを実施してボトルネックを特定する方法は、この記事で説明した方法と同じです。アプリケーションの特性を理解するためには、アプリケーションの使用率が低いユーザー負荷が少ない状態から、使用率がピークのユーザー負荷が高い状態までを、テストする必要があります。また、パフォーマンス劣化の原因を突き止められるように、アプリケーションや環境に変更を加えるたびに、重要な指標を比較用に記録することも欠かせません。そして、パフォーマンスを分析する際には、分析作業を容易にする IBM Health Center のツールであるガーベッジ・コレクション、メソッド・プロファイリング、およびロック・プロファイリングの各ビューを利用して、アプリケーションが可能なかぎり効率的に動作するようにしてください。

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=WebSphere
ArticleID=861126
ArticleTitle=WebSphere Application Server のパフォーマンス・テストと分析
publish-date=03122013