J2EEのベストプラクティス・トップ10(+2)(後編)

Kyle Brown, Senior Technical Staff Member, IBM Software Services for WebSphere
Keys Botzum, Senior Consulting I/T Specialist, IBM Software Services for WebSphere
Ruth Willenborg, Senior Manager, IBM WebSphere Performance
2004/8/7


主な内容
6.EJBコンポーネントを利用するときは、Session Facadeを常に使うこと
7.ステートフルSession BeanではなくステートレスSession Beanを使うこと
8.CMT(Container Managed Transaction)を使うこと
9.プレゼンテーション手段としてはJSPを最優先に使うこと
10.HttpSessionにはビジネス・ロジックに必要な最小限のデータだけを保管すること
11.WebSphereでは、ダイナミック・キャッシング機能をオンにし、サーブレット・キャッシング・メカニズムを利用すること
12.O/Rマッピングの手段として、まずはCMP Entity Beanを利用し、プログラマーの生産性を高めること


本記事は、IBM developerWorksからアットマーク・アイティが許諾を得て翻訳、転載したものです。

 J2EEのベストプラクティスについては、過去5年にわたり多数の文章が記されてきている。J2EEアプリケーションの開発ノウハウを解説した記事は数多く公表されており、出版された書籍もおそらく10を超えるだろう。J2EEに関する情報源はあまりにも多いため、互いに矛盾する方針を示していることもある。実際のところ、この“情報の迷路”こそが、J2EE導入における障害となっていたのである。

 筆者らは、この迷路でさまよえる読者に向けた簡単なガイドとして、J2EEにおける最も重要なベストプラクティスのトップ10リストを作成した。ただし、WebサービスもJ2EEの一部分として含めたところ、リストの項目は10を超えてしまった。そこでここでは、成長を続けるJ2EEに敬意を表し、トップ10の代わりに「トップ12リスト」とすることにしたい。

 後編ではトップ6から12までを紹介しよう(項目1から5までは「前編」を参照)。

  1. 必ずMVCを使うこと
  2. すべてのレイヤにテストツールを用意し、ユニットテストを自動化すること
  3. アプリケーション・サーバの仕様ではなく標準仕様に基づき開発すること
  4. J2EEセキュリティの利用を当初から検討すること
  5. 理解できる範囲でビルドすること
  6. EJBコンポーネントを利用するときは、Session Facadeを常に使うこと
  7. ステートフルSession BeanではなくステートレスSession Beanを使うこと
  8. CMT(Container Managed Transaction)を使うこと
  9. プレゼンテーション手段としてはJSPを最優先に使うこと
  10. HttpSessionにはビジネス・ロジックに必要な最小限のデータだけを保管すること
  11. WebSphereでは、ダイナミック・キャッシング機能をオンにし、サーブレット・キャッシング・メカニズムを利用すること
  12. O/Rマッピングの手段として、まずはCMP Entity Beanを利用し、プログラマーの生産性を高めること
6. EJBコンポーネントを利用するときは、Session Facadeを常に使うこと

 どのような種類のクライアントに対しても、Entity Beanを直接公開してはならない。また、Entity Beanではローカル・インターフェイスのみ用いること。

 Session Facadeパターンは、EJBコンポーネントの利用に際して、最も広く定着しているベストプラクティスの1つである。実のところ、このパターンは、CORBAやEJB、DCOMなどのあらゆる分散テクノロジー分野で用いられている普遍的なルールを表したものだ。つまり、アプリケーションにおける「ネットワークの横断」をなるべく減らすという原則である。これにより、細かなデータがネットワーク上を何度も行き交うことによるオーバーヘッドの発生を防止できる。

 Session Facadeを実装するには、複数の細かなロジックを包括した大きなファサード・オブジェクトを作成し、1回のメソッド呼び出しだけで主要なビジネス・ロジックを実行できるよう設計する。その結果、ネットワークのオーバーヘッドが抑えられる仕組みだ。さらにEJBでは、ビジネス・ロジック全体を含んだ1つのトランザクションを構成できるため、データベース・アクセスの回数を大幅に減らすことができる。

 なお、Session Facadeについては、Kyle Brown氏の「Enterprise Java Programming with IBM WebSphere, 2nd Edition」(Addison-Wesley、2003)にて詳しく説明されている。また、同パターンの基本形を解説した書籍としては、Deepak Alur氏らによる「Core J2EE Patterns, 2nd Edition」(Addison-Wesley、2003)がある。さらにほかの文献として、EJBを超えた普遍的なパターンとして解説しているMartin Fowler氏の「Patterns of Enterprise Application Architecture」(Addison-Wesley、2002)や、Floyd Marinescu氏の「EJB Design Patterns」(John Wiley & Sons、2002)がある。

 さて、EJB 2.0仕様では、同じJVM内で動作するEJBコンポーネント間のアクセス・パフォーマンスを最適化する手段として「ローカル・インターフェイス」が新たに導入された。このローカル・インターフェイスを利用するには、同インターフェイスを呼び出すようにアプリケーション・コードを書き換えなければならない。また、後になってEJBコンポーネントを異なるJVMに分散させることになれば、再びコードを元に戻す必要が生じる。そのため、Session Facade(通常はステートレスSession Bean)は、従来どおりリモート・インターフェイスを用いて設計しておくことを勧める。一方、その背後で動作するEntity Beanは、Session Facadeと同じJVM内で動作するため、ローカル・インターフェイスを利用すべきである。

 ただ実際のところ、少なくともWebアプリケーションでは、EJBクライアントとEJBコンポーネントが同じJVM内で動作するケースが多い。そうしたときはSession Facadeについてもローカル・インターフェイスを導入し、パフォーマンスを最適化すべきだろう。また、WebSphere Application Server(WAS)の「No Local Copies(ローカルコピー禁止)」機能のようなアプリケーション・サーバの最適化設定を利用すれば、ローカル・インターフェイスを使用せずともそれと同等の効果が得られる。いずれの方法にせよ、メソッド呼び出しのメカニズムがオブジェクトの値渡し(pass by value)から参照渡し(pass by reference)に変化することに気を付けてほしい。この違いは厄介なバグの原因ともなりかねないので、ローカル・インターフェイスの導入についてはプロジェクトの当初から検討しておくべきだろう。

 一方、Session Facadeにリモート・インターフェイスを用いることのメリットは、J2EE 1.4準拠のWebサービスとしてSession Facadeを公開できることだ。J2EE 1.4のWebサービス・デプロイメントについて規定するJSR 109では、EJB WebサービスとEJBコンポーネント間のインターフェイスとして、ステートレスSession Beanのリモート・インターフェイスを使用することを定めている。Webサービスをサポートすれば、より多くの種類のクライアントからSession Facadeのビジネス・ロジックを利用できるようになるだろう。

7. ステートフルSession BeanではなくステートレスSession Beanを使うこと

 ステートレスSession Beanを用いることで、システムのフェイルオーバーをより容易に実現できる。個々のユーザーの状態を保持するにはHttpSessionを利用すべし。

 筆者らにとって、ステートフルSession Beanはすでに過去の技術である。同Beanは、いわゆるCORBAオブジェクトとまったく同じメカニズムで動作する。すなわち、1台のサーバに縛られ、最後までそのサーバに依存し続けるオブジェクトである。もしサーバがダウンすれば、クライアントにとって不幸なことに、ステートフルSession Beanが保持していた内容は失われてしまう。

 J2EEアプリケーション・サーバに備わるステートフルSession Beanのフェイルオーバー機能を使えば、サーバのダウンに対してある程度の対策は可能である。とはいえ、ステートレスSession Beanに比べれば、そのスケーラビリティの低さは否めない。例えばWASでは、ステートレスSession Beanに対するリクエストが、クラスタを構成するすべてのサーバに向けて負荷分散される。対照的に、ステートフルSession Beanへのリクエストは負荷分散できない。そのため、サーバ間の負荷にばらつきが発生し得るのである。
 頑丈な分散システムを構築するための原則は、できる限りステートレスな設計とすることだ。しかしステートフルSession Beanを利用するには、アプリケーション・サーバ上にセッション情報を保持しなくてはならない。その結果システムが複雑になり、トラブル時の対応も面倒なものとなってしまう。

 こうした理由から、大半のアプリケーションについてステートレスSession Beanを選択することをお勧めする。ビジネス・ロジックの処理に必要なユーザーごとのセッション情報は、HttpSessionなどの機能によりEJBの外側に保持し、EJBへのメソッド呼び出し時に引数として渡せばよい。もしくは、EJBのトランザクションの実行時に、Entity Beanなどを用いてバックエンドのデータベースから読み込む方法もある。

 また、アプリケーション・サーバのメモリ上にセッション情報のキャッシュを適宜保存することも可能だ。ただし、分散システムではキャッシュ間の整合性にまつわる問題が起こり得ることも留意すべきだろう。こうしたキャッシュのメカニズムは、データがリードオンリーのときに最も効力を発揮する。

 結局のところ、プロジェクトの当初からスケーラビリティについて計画を立てておくことが重要である。システムの設計を見直し、サーバを2台以上に増やしても問題なく動作するかどうかチェックする。このルールは、アプリケーションのコードに限らず、MBeansや管理用インターフェイスの設計にも当てはまる。

 そして、ステートフルな設計を避けること。これはJ2EEの設計の基本原則であって、IBM製品に固有の制限に由来するわけではない。例えばTyler Jewell氏の記事「Stateful Session Beans: Beasts of Burden」(OnJava.com)では、筆者らの主張と同様に、ステートフルSession Beanへの厳しい意見が紹介されている。

1/3

 INDEX

Eclipseのカスタマイズの勧め(後編)
Page1
6.EJBコンポーネントを利用するときは、Session Facadeを常に使うこと
7.ステートフルSession BeanではなくステートレスSession Beanを使うこと
  Page2
8.CMT(Container Managed Transaction)を使うこと
9.プレゼンテーション手段としてはJSPを最優先に使うこと
  Page3
10.HttpSessionにはビジネス・ロジックに必要な最小限のデータだけを保管すること
11.WebSphereでは、ダイナミック・キャッシング機能をオンにし、サーブレット・キャッシング・メカニズムを利用すること
12.O/Rマッピングの手段として、まずはCMP Entity Beanを利用し、プログラマーの生産性を高めること

Java Solution全記事一覧





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

注目のテーマ

Java Agile 記事ランキング

本日 月間