EJB複数指定機能は、数台のEJBサーバを使用した運用環境を対象として、各サーバで同一のEJBセションBeanを起動しそれらを1つのグループとして登録しておくことにより、以下の機能を実現します。
EJBサーバがダウンした場合でも他のサーバのセションBeanを呼び出すことにより、業務を継続して実行します。
呼び出すセションBeanを順次切り替えることにより、簡易的な負荷分散を実現します。
EJB複数指定機能で呼び出せるのはApcoordinatorで作成したセションBeanです。
EJBの呼び出しにはリモート共通インタフェースを使用します。EJB複数指定機能を使用しないでセションBeanを呼び出す場合と呼び出し方法が共通です。
EJBの作成
Apcoordinatorのフレームワークを使用してセションBeanを作成します。作成方法は“第4部 EJBアプリケーションの開発”を参照してください。
EJB複数指定機能を使用して呼び出されるセションBeanは、作成時に以下の点に注意してください。
セションBeanのアプリケーションクラスのインスタンスは各JVMごとに存在します。そのため、アプリケーションクラスにデータを保存した場合、そのデータは他のEJBサーバにあるセションBeanとは共有されません。 EJB複数指定機能を使用した場合、常に同じEJBサーバのセションBeanが呼び出されるとは限らないため、前回の呼び出しでアプリケーションクラスに保存したデータが次回の呼び出しで読み出せるとは仮定できません。
EJBの呼び出し方法
EJB複数指定機能を使用してEJBを呼び出すには、リモート共通インタフェースを使用し、EJBを呼び出すアプリケーションを以下のように作成します。
リモートマップを作成して、セションBeanのグループを定義し名前を付けます。 以下はリモートマップの記述例です。MySessionBean1, MySessionBean2, MySessionBean3 の3つのセションBeanからなるグループをMySessionBeansという名前で定義しています。
<?xml version="1.0" encoding="Shift_JIS"?> <remoteMap xmlns=http://interstage.fujitsu.com/schemas/uji/remoteMap xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation="http://interstage.fujitsu.com/schemas/uji/remoteMap http://interstage.fujitsu.com/schemas/uji/remotemap.xsd"> <config> <version>5.0</version> </config> <!-- EJB複数指定機能を使用して呼び出すセションBeanのグループを定義します。--> <ejbExt name="MySessionBeans" type="proxy" recovertime="10" > <application name="java:comp/env/ejb/MySessionBean1" /> <application name="java:comp/env/ejb/MySessionBean2" /> <application name="java:comp/env/ejb/MySessionBean3" /> </ejbExt> </remoteMap>
グループはejbExtタグで定義します。ejbExtタグのnameアトリビュートにグループの名前を記述します。ejbExtタグのコンテントには、グループのメンバであるセションBeanをapplicationタグで記述します。applicationタグのnameアトリビュートにはJNDIで検索するセションBeanの名前を指定します。
com.fujitsu.uji.ext.CallFactoryとcom.fujitsu.uji.ext.Callの2つのインタフェースを使用してセションBeanを呼び出します。まず、CallFactoryインタフェースのcreateCallメソッドを実行してCallインタフェースを取得します。createCallの引数にはグループの名前を指定します。続いて、データBeanとコマンド名を引数としてCallインタフェースのinvokeメソッドを呼び出すことにより、リモートマップで定義したグループからセションBeanが選択され、呼び出されます。以下はビジネスクラスからセションBeanを呼び出す例です。
public Object doSomething(DispatchContext context, DataBean dataBean){ CallFactory factory = context.getCallFactory(); // グループを指定してCallオブジェクトを取得します。 Call call = factory.createCall("MySessionBeans"); // 送信するデータとコマンド名を指定してセションBeanを呼び出します。 ResponseBean response = (ResponseBean)call.invoke(dataBean,"update"); ... }
ポイント
リモート共通インタフェースは、呼び出されるアプリケーションの種別に依存せずに、リモートマップでアプリケーションに名前を定義し、CallFactoryインタフェースでその名前を指定して呼び出すという統一された方法でアプリケーションを呼び出します。 EJB複数指定機能を使用する場合は、アプリケーションの名前の代わりにセションBeanのグループの名前を使用します。リモートマップのejbExtタグで定義する名前やCallFactoryインタフェースのcreateCallメソッドの引数に与える名前は、アプリケーションの名前ではなくグループの名前になります。
EJBの選択方式
Callインタフェースのinvokeメソッドを実行すると、リモートマップで定義したグループからセションBeanが1個選択されて呼び出されます。セションBeanを選択する方式には以下の2通りがあり、リモートマップに記述したejbExtタグのtypeアトリビュートで指定します。
proxy
グループ内で利用可能なセションBeanのうち、最も優先度が高いものを選んで使用します。 EJBコンテナのダウンによりセションBeanが利用不能になった場合は、グループ内の別のセションBeanを代わりに使用します。すべてのセションBeanが利用不能な場合は例外が発生します。
セションBeanの優先度はejbExtタグのコンテントに書いた順番で与えられ、最初に書いたセションBeanが最優先となります。 上記のリモートマップの記述例の場合、通常はMySessionBean1が使用されます。MySessionBean1が利用不能な場合はMySessionBean2が使用されます。MySessionBean1、MySessionBean2両方とも利用不能な場合はMySessionBean3が使用されます。
round
セションBeanを使用するたびに、使用するセションBeanを順番に切り替えます。 EJBコンテナのダウンによりセションBeanが利用不能になった場合は、次のセションBeanを代わりに使用します。すべてのセションBeanが利用不能な場合は例外が発生します。
セションBeanを切り替えるタイミングは、CallFactoryインタフェースのcreateCallメソッドを呼び新規にCallオブジェクトを作成した時点です。上記のリモートマップの記述例の場合、createCallメソッド呼び出すごとに、MySessionBean1、MySessionBean2、MySessionBean3、MySessionBean1、...の順で使用されます。MySessionBean2を使用しようとしてEJBコンテナのダウンが検出された場合は、代わりにMySessionBean3が使用されます。
同一のCallオブジェクトを使用している間は、invokeメソッドを繰り返し呼び出しても同一のセションBeanが使用されます。ただし、後述するcreateOnInvokeアトリビュートにtrueが指定されている場合で、EJBコンテナのダウンが検出された場合は、別のセションBeanを代わりに使用します。
EJBコンテナがダウンしているかどうかの判定はセションBeanオブジェクトの作成時 (ホームインタフェースのcreateメソッド呼び出し時) に行われます。セションBeanオブジェクト作成時に以下の現象が発生するとEJBコンテナがダウンしていると判断します。
JNDIによる検索でホームインタフェースを取得する際に例外が発生した
ホームインタフェースのcreateメソッドを実行してリモートインタフェースを取得する際に例外が発生した
ホームインタフェース、リモートインタフェースは取得できたが、Apcoordinatorで作成したセションBeanではない
EJBコンテナがダウンしたと判定された場合、そのセションBeanはその後一定期間は使用されません。この使用されない期間はejbExtタグのrecovertimeアトリビュートに指定します。単位は分です。デフォルトは10分です。
セションBeanオブジェクトを新規に作成するタイミングは以下の2通りから選択でき、ejbExtタグのcreateOnInvokeアトリビュートで指定します。
Callオブジェクト1個に付き、1回だけセションBeanオブジェクトを作成します。一度作成したセションBeanオブジェクトは、Callオブジェクトを破棄するまで使用されます。EJBコンテナのダウン判定はCallオブジェクト作成後最初のinvoke実行時に行われ、それ以降は行われません。一度作成したセションBeanオブジェクトをそのまま使用し続けるため、厳密なダウン判定より性能を優先する場合は、このタイミングを選択します。デフォルトではこのタイミングです。
Callオブジェクトのinvokeメソッドを呼び出すたびに、新しくセションBeanオブジェクトを作成します。この場合、EJBコンテナのダウン判定がinvokeメソッド実行時に毎回実施されるため、ダウン判定をより厳密に行いたい場合はこのタイミングを選択します。 このタイミングを選択するには、ejbExtタグのcreateOnInvokeアトリビュートにtrueを指定します。 なお、invokeメソッドを実行するたびに実際に呼び出されるセションBeanオブジェクトが替わるため、このタイミングを使用してステートフルセションBeanを呼び出すと、EJB複数指定機能を使用せずに呼び出した場合と実行結果が異なる場合があります。そのため、ステートフルセションBeanの呼び出しにはこのタイミングを使用できません。
実行環境設定時の留意事項
EJB複数指定機能を使用する場合、実行環境の設定に関して以下の留意事項があります。
EJB複数指定機能を使用する場合、EJBクライアントから複数のEJBサーバにアクセスできるようにアプリケーションサーバを設定する必要があります。
Interstageを使用する場合は、Interstage管理コンソールまたはInterstage統合コマンドを使ってInterstageを設定することにより、ネーミングサービスを1台のサーバ上で運用し、 EJBクライアントを運用するサーバと全てのEJBサーバがそのネーミングサービスを参照するように設定します。設定方法の詳細は、「Interstage Application Server 運用ガイド(基本編)」や、Interstage管理コンソールのヘルプを参照してください。
複数のEJBサーバへ配備されたセションBeanには、それぞれ違う名前(JNDIで検索する名前)を付ける必要があります。
Interstageを使用する場合、セションBeanの名前を指定するには、Interstage管理コンソールを使用し、配備時にEJBアプリケーション名を変更します。 EJBアプリケーション名をfooとした場合、"java:comp/env/ejb/foo"がJNDIで検索する名前になります。 Interstage StudioからセションBeanを配備する場合、配備時にEJBアプリケーション名を変更するにはInterstage管理コンソールを使用します。