次に、EJBにおけるパフォーマンスチューニング項目を見ていきます。
EJBには、大きく分類して3つのタイプ(セッションBean、エンティティBean、そしてEJB 2.0で追加されたメッセージ駆動型Bean)があります。それぞれのEJBのタイプごとに役割や性質が異なるため、パフォーマンスに影響を与えるBeanのリソース管理方法や同時アクセス性もタイプによって異なります。各タイプの特性をよく知ることで、性能の引き出し方も見えてきます。
ステートレスセッションBeanは、会話ステートを持たないBeanです。1つの処理がステートレスBeanの中で完結して結果を返すような処理に使われます。例えば、現在の株価を返したり、クレジットカードの有効性を検証するサービスなどがそのよい例です。会話ステートを持たないので、クライアントが初回に呼び出したメソッドと、次回呼び出したときのメソッド間での関連はまったくありません。そのためステートレスセッションBeanはステートフルセッションBeanと異なり、あるクライアントに専任するのではなく任意のクライアントに対応します。
上述の特性により、ステートレスセッションBeanインスタンスをプールの中で保持しておき、必要に応じて使い回すというインスタンス管理方法をとることが可能になります。このプールの考え方は、前述の接続プールとよく似ています。プールの中の利用可能なインスタンスを任意のクライアントに対して使い回すことで、リソースを節約し、限られた数のインスタンスで多くの処理をさばくことが可能です。
このインスタンスプールに関連するパラメータをどのように設定するかによって、ステートレスセッションBeanのパフォーマンス性能に差が出る場合があります。
性能改善のポイント
●プール内のステートレスセッションBeanインスタンスの数を最適化しましょう!
■ ステートレスセッションBeanの設定
WLS61固有の設定になるので、weblogic-ejb-jar.xmlに記述します。設定項目は以下のとおりです。
・<initial-beans-in-free-pool>
WLS61起動時、プールに生成するインスタンスの数を指定します。指定しない場合には、起動時生成されるインスタンス数は0です。
・<max-beans-in-free-pool>
プールに生成するインスタンス数の最大値を指定します。デフォルトの設定では、最大値を設定していません。現実的には、同時にサービス提供できるインスタンス数は、スレッド数によって制限されてしまいます。
WLS61のドキュメントでは、<max-beans-in-free-pool>を設定しないよう推奨しています。
<stateless-session-descriptor> <pool> <max-beans-in-free-pool>30</max-beans-in-free-pool> <initial-beans-in-free-pool>5</initial-beans-in-free-pool> </pool> </stateless-session-descriptor>
ステートレスセッションBeanの動作とweblogic-ejb-jar.xmlの関連は以下のとおりです。
ステートレスセッションBeanと異なり、ステートフルセッションBeanは会話ステートを保持するBeanです。クライアントのメソッド間で会話ステートを保持するために、1つのクライアントに対して1つのステートフルセッションBeanが張り付き(正確にはEJBオブジェクトに対して)、Beanライフサイクルの間専任します。そのためステートレスセッションBeanのように、インスタンスプーリングでスワップするメカニズムは使えません。また、ステートフルセッションBeanは、ステートレスセッションBeanに比べ、会話ステートのやりとりなどにおいて、処理が完了するまでの時間は長くなりがちです。
クライアントの数が増える分だけステートフルセッションBeanの数が増えていくのではリソース管理に破たんをきたしてしまいます。そこでステートフルセッションBeanの場合、Beanインスタンスが活動しない間、コンテナがBeanの会話ステートを2次記憶装置に保存し、キャッシュからBeanインスタンスを取り除くことでインスタンスの管理を行っています。この会話ステートをキャッシュから2次記憶装置に保存するメカニズムをパッシベーション、また2次記憶装置からキャッシュに戻すことをアクティベーションと呼んでいます。
キャッシュ内のリソースを適切なレベルに保つために、以下の条件のインスタンスはパッシベートされる候補となります。
性能改善のポイント
●パッシベーション/アクティベーション処理を減らすよう、キャッシュ内のインスタンス数を最適化しましょう!
■ステートフルセッションBeanの設定
WLS61固有の設定になるので、weblogic-ejb-jar.xmlに記述します。設定項目は以下のとおりです。
・<max-beans-in-cache>
キャッシュに保持可能なステートフルセッションBeanのインスタンス最大数を指定します。
・<idle-timeout-seconds>
指定された時間を経過したインスタンスは、コンテナによってキャッシュから破棄されます。これにより、ステートフルセッションBeanインスタンスがキャッシュに長く居座ることを防ぎます。
記述例は以下のとおりです。
<weblogic-enterprise-bean> <ejb-name>AccountBean</ejb-name> <stateful-session-descriptor> <stateful_session-cache> <max-beans-in-cache>200</max-beans-in-cache> <idle-timeout-seconds>1200</idle-timeout-seconds> </stateful-session-cache> </stateful-session-descriptor> </weblogic-enterprise-bean>
エンティティBeanは、永続化されたデータのオブジェクトビューを表現します。1つのエンティティBeanインスタンスは、データベースのあるレコード行に対応します。レコード行がそうであるように、エンティティBeanも複数クライアントからの同時アクセスに対応することが求められます。また、データを表現しているので、トランザクションを考慮してデータの完全性も維持しなくてはいけません。エンティティBeanは、データの完全性と同時アクセスの性能という、本来相反する要求を満たさなければならない大変難しい立場にあるBeanであるといえるでしょう。
■エンティティBeanに関する設定
EJBコンテナは、あるタイミングでデータベースからレコードのデータをBeanへ読み出したり(ejbLoad())、またその逆にあるタイミングでBeanのデータをデータベースに保存しようとします(ejbStore())。このときBeanインスタンスとデータベース間でのアクセスが頻繁に発生すると、処理性能の低下を引き起こしてしまいます。データベースへの不要なアクセスを減らすようにすることで、性能の低下を抑えることが可能です。weblogic-ejb-jar.xmlの以下の項目が関連します。
項目 | デフォルト値 | |
---|---|---|
<delay-updates-until-end-of-tx> | true | |
上記の設定で、トランザクションコミット時にのみejbStore()を呼び出すように制限されます。不要な更新とejbStore()の呼び出しの反復が回避され、一般にパフォーマンスが向上します。パフォーマンスを重視する場合はデフォルト値のままにしてください。
●読み出し専用(Read-Only)エンティティBean
例えばクライアントからみた場合、データ読み出し専用のBeanインスタンス(外部リソースによって更新される株価表示や商品一覧など)があるとします。このBeanは読み出し専用なので、更新処理(ejbStore())は必要ありません。また、それほど頻繁に更新されないデータであれば、初回にBeanが生成されるときにデータを読み込んでおいて(ejbLoad())、その後のアクセスはキャッシュされたBeanを共有して使用すると、データベース・アクセスを大幅に減らすことができ、エンティティBeanの性能が大幅に向上すると考えられます。
WLS61では、用途に合わせて3つのパターンを選択できます。
項目 | 内容 |
---|---|
Read-Onlyパターン | Beanを読み出し専用にする。ejbStore()は呼び出されないので、更新はできない。EJB作成時に初回のejbLoad()が呼び出され、以後 |
Read-Writeパターン | 通常のRead/Writeパターン |
Read-Mostlyパターン | Read-OnlyパターンとRead-Writeパターンの組み合わせ型。参照系ではRead-Onlyパターンを使用し、更新系ではRead-Writeパターンを使用する |
●同時アクセス方法
前述しましたが、データベースのレコード行がそうであるように、エンティティBeanも同一プライマリキーを持った、異なる複数クライアントからの同時アクセスに対応する必要があります。WLS61では、以下の2つの同時アクセス方法を選択できます。
項目 | 内容 |
---|---|
Exclusive | 異なるクライアントからの同一プライマリキーによるエンティティBeanへのアクセスは直列化されます。データの完全性は保持されますが、パフォーマンスに影響があります。 |
Database (デフォルト) |
異なるクライアントからの同一プライマリキーによるエンティティBeanへのアクセスは、並行処理されます。データの完全性はデータベースに任せられ、衝突が生じた場合には、RDBがトランザクション分離レベルに応じてSQLExceptionをthrowします。 |
デフォルトの設定は以下のとおりです。
項目 | デフォルト値 | 指定値 | |
---|---|---|---|
<concurrency-strategy> | Database | Exclusive | Database | ReadOnly | |
性能改善のポイント
●ejbLoad()とejbStore()メソッド呼び出しを抑止し、不要なデータベース・アクセスを減らしましょう!
WLS61では、<concurrency-strategy>で、上述の読み出し専用エンティティBeanの指定も行っています。
●エンティティBeanの設定
今回はWLS61を例に説明していますが、他社のアプリケーション・サーバでも同様の設定が可能だと思われますので、アプリケーション・サーバのドキュメントを調べてみてください。
WLS61固有の設定になるので、weblogic-ejb-jar.xmlに記述します。以下に、記述例を紹介します。AccountBeanクラスを読み取り専用のエンティティBeanとして指定しています。
<weblogic-enterprise-bean> <ejb-name>AccountBean</ejb-name> <entity-descriptor> <entity-cache> <concurrency-strategy>ReadOnly</concurrency-strategy> </entity-cache> </entity-descriptor> </weblogic-enterprise-bean>
エンティティBeanを実用的なものにするため、EJB 2.0の仕様では、パフォーマンス向上のため、以下のような工夫が盛り込まれました。
1.メッセージ駆動型Bean
JMSと連携して非同期メッセージングをサポートします。システムによっては、メッセージングのアーキテクチャを同期型(通常、あるクライアントのメソッド処理が終了するまで、その処理はブロックされます)から非同期型に変更することで、大量アクセス処理などにおける処理性能/能力の向上が可能になる場合があります。
2.CMPの拡張
抽象アクセサメソッド(getXXX()、setXXX())が取り入れられ、コンテナが実装クラスを自動生成します。WLS61のCMPコンテナでも最適化について多くの工夫が盛り込まれており、以前のエンティティBeanに比較してかなりパフォーマンスが向上しています。拡張された主なポイントとしては、
などが挙げられます。
3.ローカルインターフェイス
同一のEJBコンテナからローカル呼び出しが可能になりました(WLS61では、EJB 2.0を採用する前から同等機能を実装済み)。パフォーマンスを考慮する場合、ローカルインターフェイスの使用が推奨されています。
Copyright © ITmedia, Inc. All Rights Reserved.