「アプリケーション・サーバを使いJ2EEべースのWebアプリケーションを構築できたのはいいが、どうも本来のパフォーマンスが出ていない」とは、よく聞く話である。本連載では、そういった事態に遭遇した場合に、具体的にどのように対処してパフォーマンスを向上させるかについて解説していく。2回は、「パフォーマンスが出ない!」という場面で、具体的にどのような対処をとったら良いのか、そのオーバービューを紹介しよう。具体的なチューニング手法は、第3回以降で詳細に解説していく。(編集局)
パフォーマンスチューニングの実際は、まずはボトルネックとなっている場所を探すことから始めます。はじめにボトルネックの目星を付けますが、どの場面で性能が出ないのかがポイントとなります。性能の評価には、負荷テストとプロファイリングを行います。
パフォーマンス・チューニングを行う状況にはさまざまなケースが考えられます。いずれの場合も、どこが遅いのか、つまりチューニング・ポイントがどこかを明確にすることから始めます。
●性能評価で性能が出ない場合
●総合テストで性能が出ない場合
●サービスイン後に性能が問題視された場合
■性能評価で性能が出ない場合
アーキテクチャ設計の段階でプロトタイプを作成し、性能評価を行ったところ思うような性能が出ない場合があります。ここで性能上の問題点を洗い出しておくことがプロトタイプ構築の目的でもあります。この段階では、性能評価作業にアーキテクチャ設計者やプロトタイプ実装者(両者を1人が兼ねている場合も多い)が参画しているはずですから、どこが怪しいか絞り込むのに時間はかかりません。プログラムの規模が小さいので、後述するプロファイラも最初からポイントを絞って効果的に使用することができます。
■総合テストで性能が出ない場合
総合テストで期待した性能に達していないことが判明した場合は、上記のケースに比べて範囲が広がりますが、テストは機能別に行うはずなので遅い処理の絞り込みは比較的容易に行うことができます。この時点では、まだサーバ設定の変更を自由に行えるので、余計な要素を除去しつつテストを行うこともできます。
■サービスイン後に性能が問題視された場合
サービスイン後しばらくして、ユーザーから「レスポンスが悪い」などといった苦情が相次ぐ場合があります。この場合、まずシステムのどのレイヤに問題があるのかを明らかにしておかないと、無駄な時間を浪費することになりかねません。殊に、高負荷時に全体的にレスポンスが悪くなるといった漠然とした状況では、実機環境のさまざまなレイヤを疑ってかかる必要があります。
最後のケースのように、漠然とレスポンスが悪いといったような状況では、どこが問題を引き起こしているのかを、まず大まかに特定する必要があります。以下、調査のポイントをいくつか述べますが、何かあった場合すぐに対応できるよう、これらの情報はシステム運用監視の一環として常時収集しておくことをお勧めします。
(1)ネットワークのボトルネック
ネットワークのボトルネック調査は、道具立てさえそろっていれば時間はかかりませんし、常時監視の仕組みを備えているサイトもありますので、最初に当たっておくべきポイントです。なお、ネットワークの監視やチューニングの方法に関しては連載の範囲外ですので、「Master of IP Network フォーラム」などを参考にしてください。
(2)サーバのボトルネック
どのサーバがボトルネックになっているのかを調べます。各サーバのCPU使用率、ディスクI/Oなどを調査し、Webサーバ、アプリケーションサーバ、データベースサーバのうちどこに負荷が集中しているのかを特定します。これらの情報は、OS
依存のコマンドで収集することになります。
(3)ボトルネックとなる処理
Webサーバやアプリケーションサーバにおいて時間のかかる処理を特定する場合は、HTTPアクセスログを利用するのが金額的にもコンピュータ資源的にも最もコストのかからない方法です。高負荷時のアクセスログをExcelなどを使って分析し、問題になっている処理を特定します。低負荷状態では短時間で終わっていた処理が、高負荷状態で著しい性能低下を起こす場合がありますので、先入観を捨ててすべての処理を疑ってください。
アプリケーションサーバの前にWebサーバを配置している構成で、両者の処理時間に著しい差が現れた場合はWebサーバの設定やWebサーバとアプリケーションサーバとの間のネットワークを疑う必要があります。
Webサーバ(Apache)、アプリケーションサーバ(WebLogic Server)の場合は、以下のような設定でアクセスログにHTTPリクエスト毎の処理時間を記録することができます。
●Apache 1.3
httpd.confでaccess_logのフォーマットを設定します。LogFormat命令のダブル・クオーテーションで囲まれた部分がフォーマットの指定で、「%T」がリクエストを受けてからレスポンスを返すまでに要した時間を表します。
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %T" combined_time_taken CustomLog logs/access_log combined_time_taken
LogFormat命令で、カスタムログフォーマットに「combined_time_taken」という名前を与えていますので、CustomLog コマンドでこのフォーマットを選択し、サーバを再起動します。Apacheの場合、処理時間を秒単位でしか記録できないのですが、これでも大まかな傾向は把握することができます。
●WebLogic Server 6.X
access.logファイルの先頭に以下の行を挿入してフォーマットを設定します。Fieldsの「time-taken」キーワードがリクエストを受けてからレスポンスを返すまでに要した間を表します。
#Version: 1.0 #Fields: date time c-ip s-ip cs-method cs-uri cs-uri-query sc-status bytes time-taken
さらに、consoleの「サーバ > ログ > HTTP」の「フォーマット」で「extended」を選択し、サーバを再起動します。WebLogic Serverでは、処理時間をミリ秒単位で記録することができます。
(4)アプリケーション・ロジック
前もって、アプリケーションに処理時間を記録する仕組みを組み込んでおくのも有効な方法です。むやみに記録してもオーバーヘッドとノイズが増えるばかりですので、以下のようなポイントに絞って記録します。
●クライアントからの呼び出し
●コントローラ・フレームワークからアプリケーション処理の呼び出し
●バックエンド・システム(レガシーなど外部のシステム)の呼び出し
●まとまったデータベースの更新/検索処理
これらのポイントについて情報を収集し、性能劣化の原因となっている(あるいは、なっていそうな)個所が特定できたらいよいよチューニング作業を行います。以下、アプリケーションサーバのレイヤを中心にチューニング作業の概要を説明していきましょう。
アクセスログなどから処理時間のかかるHTTPリクエストが絞り込めたら、その処理単独で性能測定を行います。負荷の低い状態では性能の劣化が顕在化しない場合が多いので、ここで負荷テスト用のツールを使用します。
一般に、システムの性能はレスポンスタイムとスループットという2つの側面で表すことができます。クライアント数(並行して処理するリクエスト数)が上がると、スループットは向上していきますが、レスポンスタイムは逆に低下(増長)します。クライアント数の増加とともに、ある時点を境にスループットの伸びが止まり(あるいは逆に低下し)、レスポンスタイムが急速に低下(増長)していきます。ここで行う負荷テストは、上記の限界点より手前の中程度の負荷レベル(同時アクセス数)で行います。
さまざまなベンダから負荷テストツールが提供されていますが、スポットで行うチューニング作業であれば「Microsoft Web Application Stress Tool」(http://webtool.rte.microsoft.com/)を利用するのがよいでしょう。高価なツールに比べれば機能は少ないですが、チューニングの効果を確認するにはこれで十分です。1つのHTTPリクエストやEJBをマルチ・スレッドで繰り返し呼び出すようなプログラムを自作して測定しても構いません。まず、チューニング前の性能を測定しこれをベースの性能とします。
ボトルネックになっているコードの特定には、Javaのプロファイリング・ツール(プロファイラ)を使用するのが便利です。プロファイラを使用することによって、以下のことがわかります。
●どのメソッドが処理時間を消費しているのか
●どのメソッドが頻繁に呼び出されているのか
●どのオブジェクトがヒープを大量に消費しているのか
また、プロファイラとしては、以下のものを使用するのが一般的です。
純粋なプロファイリング機能としてはJ2SDKのプロファイラでも用が足りますが、結果をGUIでレポートしてくれる市販のツールの方が使い勝手は当然上です。個人的には
Optimizeitのインターフェイスが気に入っていますが、機能的にはJProbeも遜色がありません。
プロファイラを組み込んだ状態で、負荷ツールで負荷をかけ、ボトルネックになっているメソッドや、ヒープを圧迫しているオブジェクトを特定します。単独の処理を走らせて計測してもよいのですが、負荷をかけることによってボトルネックになっている個所とそうでない個所の差がより顕著に現れます。
アプリケーションのチューニングを行った後に再度負荷テストを行い、チューニングの効果を測定します。以降、「チューニング → 負荷テスト」のサイクルを目的の性能に達するまで繰り返すことになります。
Copyright © ITmedia, Inc. All Rights Reserved.