第10回 パフォーマンス低下の原因と対策を考える


樫山友一
2002/10/22


 今回のテーマはJ2EEアプリケーションサーバのパフォーマンスチューニングです。パフォーマンスの80%は設計時に決まってしまっていると思って間違いないのですが、単純なミスなどで低下してしまうこともあります。論理立てて、どの部分がボトルネックになっているかを判断する必要があります。今回はその手順について解説します。

   パフォーマンスチューニング低下の原因と対策

 まず、Webサイトの構成からボトルネックになる可能性のある部分を見てみましょう(図1)。(1)〜(3)に分けて順番に検証していきます。

図1 ボトルネック部分

(1) HTTP サーバの高負荷によるパフォーマンスの低下

原因(A)ファイルの送り出し

 HTTPサーバの大きな役割は、静的なファイルをブラウザに送り返すことです。すなわち、サイズが大きい画像ファイルを多く含むページが多い場合で、頻繁にダウンロードを求められる場合に負荷が高くなります。HTTPサーバの負荷が高くなると、当然J2EEアプリケーションサーバへ中継している通信の処理も遅くなるために、全体的にパフォーマンスが低下することになります。

原因(B)SSL

 SSLを利用しているページが多い場合にパフォーマンスが劣化することがあります。SSLを利用すると約30%CPUの処理を多く必要とします。

対策

 (A)、(B)ともにHTTPサーバの処理能力を上げることが第1です。その前に、ネットワークの負荷が原因になっていないかを確認します。インターネットへのネットワーク回線の負荷が高く、それがボトルネックになっている可能性もあります。ネットワークアナライザなどで負荷を確認し、負荷が高いようであれば回線容量をアップします。HTTPサーバの処理能力向上には、以下の2つの方法が考えられます。

 SSLによるパフォーマンス劣化の場合は、SSLを利用するページを少なくするのもチューニングの1つです。

(2)J2EEアプリケーションサーバのパフォーマンスの劣化

図2 アプリケーションサーバ内部

 アプリケーションサーバ内のパフォーマンスの劣化を解析するのは困難です。図2に関連しそうなアプリケーションサーバの内部構造の概要を示します。以下に各部分に対するパフォーマンス劣化の原因と対策を示します。

(A) Servlet、JSPエンジン

 Servletには、シングルインスタンスモデルとマルチインスタンスモデルを選択して利用することができます。一般的には、シングルインスタンスモデルで利用しますが、マルチインスタンスモデルで利用する場合には注意が必要です。マルチインスタンスモデルを用いた場合は、同時にアクセスするユーザーが多いと、ユーザーごとにServletのインスタンスが生成されるため注意が必要です。

(B) セッション管理

 次に、アプリケーションサーバがクラスタ構成を取っている場合のパフォーマンスの劣化についてです。この場合は、HTTPセッションに大きなデータを入れている場合に問題が発生します。アプリケーションサーバは、クラスタ内でセッション情報を共有するために、セッション情報が多いとオーバーヘッドが多くなります(図3)。

 実際には、HTTPセッションはハードディスクに保存されたり、クラスタ内でほかのサーバのメモリ上にコピーされるなどの方法で永続化されます(図4)。

図3 セッションの保存

図4 セッション情報のコピー

(C) EJBエンジン

 EJBでパフォーマンスが問題になるのは、Entity Beanを用いているケースが多くなります。Entity Beanは、データベースにあるデータをread/writeするために用いられますが、アプリケーションサーバ製品によってデータベースのアクセス頻度などがまちまちです。EJBの仕様では、Entity Beanに2つの種類があります。

CMP(Container Managed Persistence) EJBのコンテナ(EJBを管理しているアプリケーションサーバのエンジン)が、EJBのインスタンスの持つデータとデータベースにあるデータが同一になるように管理を行う
BMP(Bean Managed Persistence) Bean(ユーザーがコーディングしたEJBのクラス)クラスが、データベース内のデータとEJBのインスタンスが同一になるように管理する

 CMP、BMPの両者ともにデータベースのアクセスの頻度が多くなるとパフォーマンスの低下を招くことになります。よって、一度アプリケーションサーバ上にロードしたデータはなるべくキャッシュとして利用するような実装にする必要があります。

(D) データベースへのアクセス

 アプリケーションサーバでは、データベースへのコネクションをコネクションプールとして扱う仕組みがあります。これは、アプリケーションサーバからデータベースへ接続を行う処理にコストがかかるからです。よって、ブラウザやアプリケーションサーバからの要求のたびにデータベースへの接続を行っているような場合は、処理が遅くなることになります。アプリケーションサーバのコネクションプールを利用するようにソースコードを変更する必要があります。

 コネクションプールは、アプリケーションサーバ起動時に複数のコネクションをデータベースとの間に確保します。アプリケーションサーバ内のアプリケーションは、必要に応じてコネクションプールからコネクションを取り出して利用します。このコネクションプールの数が不足している場合にパフォーマンスの低下が見られることがあります。これは、コネクションプールからのコネクションの取得待ちになっているスレッドが多い場合に発生します。対策としては、コネクションプールの数を増やすことですが、データベースへのコネクションは、コンピュータのリソースをより多く必要とします。コネクションプールの数を増やしすぎると逆にパフォーマンスが低下することになります。

(3) データベースのパフォーマンスの劣化

 データベース自体のパフォーマンスチューニングは、アプリケーションサーバの利用には依存しません。一般的なデータベースのチューニングを行うことで対応可能です。

   パフォーマンスチューニングの一般的な方法

 アプリケーションサーバを用いた場合には、前述のような原因が考えられます。実際には、それほど単純ではなく、開発したコードの中にパフォーマンスを低下させる原因があることがほとんどです。では、これをどのように見つけていけばいいのでしょうか? 以下に大まかな手順を示します。

1、各コンピュータの負荷データを取る HTTPサーバ、アプリケーションサーバ、データベースサーバの負荷データを取ります。負荷をかけるテストツールを用いるとよいでしょう。もし、どれかのサーバだけが高負荷状態であれば、前述のような項目を疑い原因を調査します
2、ネットワークの負荷データを取る インターネットへの回線、HTTPサーバ、アプリケーションサーバ、データベースサーバの間でのネットワークの負荷データを取ります。ネットワークの負荷が高い場合は、負荷をかけているパケットが何であるかを調査します

 上記のような調査を行い、各コンピュータ(CPU使用率)やネットワークに負荷がかかっていない場合には、より深い調査が必要となります。実装するほとんどのコードは、アプリケーションサーバ内で動作するために、アプリケーションサーバがボトルネックになる可能性が最も高いといえます。まず、HTTPサーバをシステムから外してテストをしましょう。

図5 HTTPサーバの除外

 図5に示すように通常HTTPサーバにかける負荷をアプリケーションサーバに直接かけるようにします。これでも、まだ予想されるようなパフォーマンスが得られない場合には、アプリケーションサーバ内をより深くチェックすることになります。

 負荷ツールを用いてもアプリケーションサーバのCPU使用率が上がらない場合は、何かのリソースにロックがかかって、その解放を待っている状態になっています。原因として考えられるものを以下に挙げます。

コネクションプールの解放待ち まず考えられるのは、SQLの処理に時間がかかるような場合です。接続プールの数が足りないため、複数のスレッドがデータベースへのコネクションの取得待ちになります
シンクロナイズしたオブジェクトの利用 syncronizedを定義したクラスを実装している場合に発生します。特にsyncronizedが宣言されているクラスやメソッド内の処理が遅い場合にこのリソースが解放されるまでほかのスレッドが待つことになります
スレッドの待ち合わせ アプリケーションサーバ内では、ユーザープログラムがスレッドを生成して同期を取るようなケースは少ないですが、スレッドの待ち合わせについては注意が必要です

 上記のようなケースは、負荷が高い状態でデッドロック(複数のスレッドがお互いを待ち合って、ロックしてしまう現象)になりやすいものです。よって、パフォーマンスの低下とともにデッドロックを起こさないかのチェックも慎重に行った方がよいでしょう。

   パフォーマンスチューニングの目標

 最終的にどこまでパフォーマンスチューニングをするかは、難しい問題です。パフォーマンスは、使用しているハードウェアやアプリケーションサーバ製品、データベースに依存しますし、特に開発したアプリケーションの内容に大きく依存します。このくらいのハードウェアを用いて、このアプリケーションサーバ製品を用いるとこのくらいのパフォーマンスが得られるはずだというのは、かなりの開発経験を持つエンジニアでないと分からないないでしょう。一番よい方法は、利用しているアプリケーションサーバベンダの持っているデータから、リファレンスデータをもらい、パフォーマンスの測定結果と突き合わせることです。

 完成したシステムに負荷をかけると、一般的にはアプリケーションサーバが最も負荷が高くなります。アプリケーションサーバのCPU使用率が80%を超えていれば、リソース待ちなどの状況にはなっていないので、そのときのパフォーマンスが満足のいくものなら、それがそのハードウェアとアプリケーションサーバ製品を利用した場合の限界値に近いと思った方がいいでしょう。

 パフォーマンスチューニングは、ボトルネックを探す難しさと、発見後の対処方法の検討など、かなりのスキルを必要とします。アプリケーションサーバベンダのコンサルティングを利用したり、社内で経験の豊富なエンジニアを探すなどして、外部や内部の知識を効率的に用いて行うことをお勧めします。

■参考文献
「わかりやすいUML入門」オーム社
「Webサイトのわかる本」オーム社

プロフィール
樫山友一(かしやま ゆういち)

大手電機メーカー研究所でオブジェクト指向によるシステム開発に従事する。1996年よりJavaへの取り組みをはじめ、J2EEアプリケーションサーバを活用したWebシステム構築のコンサルタントとして多数のプロジェクトを手掛ける。
2001年3月にイーズ・コミュニケーションズ株式会社の設立に参加し、最高技術責任者に就任。
著書に「わかりやすいUML入門」、「Webサイトがわかる本」(いずれもオーム社)がある。


Java Solution全記事一覧



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間