WebLogic エンタープライズ JavaBeans (EJB) プログラマーズ ガイド
以下の節では、メッセージ駆動型 Bean (MDB) のライフサイクル、設計上の考慮事項、および主要な実装タスクの手順について説明します。EJB 開発の全体的なプロセスについては、「エンタープライズ JavaBean の実装」を参照してください。
MDB の概要およびアプリケーションでの典型的な使われ方については、「メッセージ駆動型 Bean による疎結合ビジネス ロジックの実装」および「メッセージ駆動型 Bean の機能」を参照してください。WebLogic JMS については、『WebLogic JMS プログラマーズ ガイド』を参照してください。
この章では、メッセージ駆動型 Bean インスタンスのライフサイクルのフェーズと MDB をコンフィグレーションしてライフサイクルを制御する方法について説明します。図 7-1 は、MDB のライフサイクルにおける主要なイベントと状態を示しています。
WebLogic Server は、現在リクエストを処理していない MDB インスタンスが配置されるフリー プールを保持します。最高の応答時間とスループットを実現するために、weblogic-ejb-jar.xml
の Bean の initial-beans-in-free-pool 要素で目的の量を指定することで起動時にプールにインスタンスを配置するよう WebLogic Server をコンフィグレーションできます。デフォルトでは、initial-beans-in-free-pool
は 0 です。
フリー プールの MDB インスタンスの数は、weblogic-ejb-jar.xml
の max-beans-in-free-pool 要素の値 (デフォルトでは 1,000)、MDB の実行キューのスレッド数、および利用可能なメモリの量によって制限されます。スレッド プールのサイズが持つフリー プールの MDB インスタンスの最大数に対する影響は、MDB がデフォルトの実行キューを使用するのか、それとも別の実行キューを使用するようにコンフィグレーションされているのかによって異なります。詳細については、「dispatch-policy」を参照してください。
MDB は、JMS 送り先からのメッセージを処理します。メッセージを受信すると、EJB コンテナは MDB の onMessage()
メソッドを呼び出します。このメソッドには、EJB が実行するビジネス ロジックが含まれています。MDB の onMessage
メソッドが呼び出されたときには、以下のアクションがとられます。
ejbCreate()
メソッド。 setMessageDrivenContext()
。Bean では、「メッセージ駆動型 Bean コンテキストの使用」で説明されているようにこのコンテキストの要素を使用できます。max-beans-in-free-pool
に達した場合、JMS onMessage()
リクエストはアクティブ MDB がメソッド呼び出しを完了するまでブロックされます。アプリケーションは、トランザクションがタイムアウトになるか、プール内の既存の Bean インスタンスが使用可能になるまで待機する必要があります。 MDB インスタンスの onMessage()
メソッドが復帰した後、リクエストは完了し、インスタンスは再利用できるようにフリー プールに配置されます (そうしても max-beans-in-free-pool
の数を超えないと想定する)。
MDB は、トピックとキューの両方で並行処理をサポートしています。トピックとキューの詳細については、「MDB とメッセージング モデル」を参照してください。
weblogic-ejb-jar.xml
の max-beans-in-free-pool 要素のデフォルト設定 (1,000) では、最高の並行処理が実現します。並行して実行されるコンシューマの数を制限する場合を除き、この値を変更しないでください。
サーバ インスタンスにデプロイされた各 MDB は、1 つの JMS 接続を作成します。
キューベースの JMS アプリケーション (ポイントツーポイント モデル) では、各 MDB インスタンスにそれ専用のセッションがあります。
トピックベースの JMS アプリケーション (パブリッシュ/サブスクライブ モデル) では、MDB のすべてのローカル インスタンスが JMS セッションを共有します。ある特定のメッセージは、複数の MDB に配信されます (サブスクライブしている各 MDB に 1 コピーずつ)。複数の MDB がデプロイされ、同じトピックをリスンする場合、各 MDB は各メッセージのコピーを受信します。メッセージは、トピックをリスンしている各 MDB の 1 つのインスタンスによって処理されます。
WebLogic Server MDB は、ポイントツーポイント (キュー) またはパブリッシュ/サブスクライブ (トピック) メッセージング モデルのいずれかで使用できます。それらのモデルの詳細については、『WebLogic JMS プログラマーズ ガイド』の「WebLogic JMS の基礎」を参照してください。
以降の節では、ポイントツーポイント メッセージング アプリケーションとパブリッシュ/サブスクライブ メッセージング アプリケーションの主な違いを説明します。
ポイントツーポイント モデルでは、JMS キューからのメッセージが 1 つの MDB リスナによって取り出され、処理されるまでキューに留まります。その MDB がダウンした場合、メッセージは MDB が再びアクティブになるのをキューの中で待ちます。
例 : ある売り場では、1 日を通して売れた品目を反映してバックエンドの在庫システムを更新する必要があります。在庫の値を減らす各メッセージは、必ず 1 度だけ処理されなければなりません。メッセージはそれが生成された直後に処理されたり、特定の順序で処理されたりする必要はないが、各メッセージが必ず処理されることが重要です。
図 7-2 は、ポイントツーポイント アプリケーションを示しています。各メッセージは、MDB_A の 1 つのインスタンスによって処理されます。メッセージ「M1」は MDB_A(1) で処理され、「M2」は MDB_A(2) で処理され、「M3」は MDB_A(3) で処理されます。
パブリッシュ/サブスクライブ モデルでは、JMS トピックがすべてのメッセージをすべてのサブスクライブ リスナにパブリッシュします。MDB リスナがダウンした場合、トピックが「恒久サブスクリプション」トピックでない限りその MDB はメッセージを逃します。
恒久サブスクリプションの詳細とコンフィグレーション手順については、『WebLogic JMS プログラマーズ ガイド』の「恒久サブスクリプションの設定」および「恒久トピック サブスクリプションのコンフィグレーション」を参照してください。
例 : 金融ニュース サービスは、株価と金融情報をサブスクライバ (ニュース配信サービスなど) にブロードキャストします。各メッセージは、各サブスクライバに配信されます。
図 7-3 は、パブリッシュ/サブスクライブ アプリケーションを示しています。ポイントツーポイント アプリケーションとは違って、パブリッシュ/サブスクライブ モデルでは、サブスクライブしている MDB それぞれの 1 つのインスタンスによって処理されます。メッセージ「M1」は、MDB_A のインスタンスと MDB_B のインスタンスで処理されます。同様に、「M2」もサブスクライブ MDB それぞれのインスタンスで処理されます。
MDB プールは、各メッセージを少なくとも 1 度処理します。メッセージは、複数回処理される場合もあります。
onMessage()
メソッドの途中、またはこのメソッドが完了した後で、メッセージが確認応答またはコミットされる前にアプリケーションで障害が起きるか、トランザクションがロールバックされるか、ホスト サーバ インスタンスで障害が発生した場合、メッセージは再配信されて再び処理されます。 メッセージが正確に 1 度処理されるようにするには、コンテナ管理によるトランザクションを使用します。そうすれば、障害が発生したときにトランザクション MDB の処理がロールバックされ、メッセージが強制的に再配信されます。
この節では、MDB をデプロイするためのさまざまな手法と MDB がリスンする JMS 送り先について説明します。
MDB は、リスン対象の JMS 送り先と同じサーバ インスタンスか、別のサーバ インスタンスにデプロイできます。それらの選択肢はそれぞれ、連結または非連結と呼ばれます。
MDB とそのリスン対象の送り先を連結すると、メッセージ トラフィックが常にローカルになり、ネットワークの往復がなくなります。連結は、WebLogic Server JMS を使用し、メッセージ処理の待ち時間とネットワーク トラフィックを最小限に抑えたい場合に最適です。
MQ Series などの WebLogic Server で動作できないサードパーティ JMS プロバイダを使用する場合は、MDB と JMS 送り先を連結できません。
図 7-4 と図 7-5 は、関連付けられた JMS 送り先をホストするサーバ インスタンスに MDB アプリケーションがデプロイされるアーキテクチャを示しています。これらのアーキテクチャは、最初のには分散送り先があり 2 番目のにはないという点で異なります。分散送り先を使用するアプリケーションでは、MDB は分散送り先セットのメンバーをホストする各サーバ インスタンスにデプロイされます。分散送り先の詳細については、「JMS 分散送り先」を参照してください。図 7-4 で示されているように、メッセージ「M1」は分散送り先と MDB_A がデプロイされている各サーバ インスタンス上の MDB_A のインスタンスに配信されます。
図 7-6 は、リスン対象の JMS 送り先とは別のサーバ インスタンスで MDB が動作するアーキテクチャを示しています。
リスン対象の JMS 送り先とは別のサーバ インスタンスで MDB を実行するのが適切なのは、以下の場合です。
JMS 送り先と MDB は、クラスタ化されていないサーバ、同じクラスタ内の複数のサーバ、または別々のクラスタのサーバにもデプロイできます。
MDB アプリケーションが WebLogic Server クラスタで動作している場合は、複数の物理的送り先 (キューまたはトピック) を、メッセージ プロデューサやコンシューマからは 1 つの送り先に見える分散送り先としてコンフィグレーションできます。
分散送り先をコンフィグレーションすると、WebLogic JMS はその分散送り先のメンバー間でメッセージングの負荷を分散します。サーバの障害が原因で送り先のメンバーがアクセス不能になると、メッセージ トラフィックは分散送り先セットのアクセス可能な他の物理的送り先にリダイレクトされます。
MDB とその関連する分散送り先を同じクラスタにデプロイすると、WebLogic Server は自動的に分散送り先メンバーを確認し、各メンバーで必ず MDB がリスンしているようにします。
MDB は、クラスタ化されている各サーバ インスタンスに均一にデプロイされます。メッセージは、複数のサーバ インスタンス上の物理的送り先間で分散され、並行して処理されます。1 つのサーバ インスタンスがダウンした場合は、クラスタの他のノードがメッセージの処理を続行できます。このアーキテクチャは、以下の場合に適切な選択肢です。
例については、図 7-4 を参照してください。分散送り先の追加情報については、『WebLogic JMS プログラマーズ ガイド』の「分散送り先の使用」を参照してください。
注意 : MDB の主要なデプロイメント要素の概要については、「要約 : MDB のデプロイメント要素」を参照してください。
以下の節の手順は、以下の JMS コンポーネントが適切に作成されているものと想定しています。
デフォルトの WebLogic MDB 接続ファクトリは XA 対応です。デフォルトの接続ファクトリについては、『WebLogic JMS プログラマーズ ガイド』の「デフォルト接続ファクトリの使い方」を参照してください。カスタム WebLogic JMS 接続ファクトリのコンフィグレーション手順については、Administration Console オンライン ヘルプの「JMS 接続ファクトリのコンフィグレーション」を参照してください。
他の JMS プロバイダでは、デフォルトの動作とコンフィグレーション方法は異なります。BEA 以外の JMS プロバイダを使用する場合は、そのベンダ提供のマニュアルを参照してください。
WebLogic JMS 送り先のコンフィグレーション手順については、Administration Console オンライン ヘルプの「JMS 送り先」を参照してください。.
注意 : JMS プロバイダがリモートの WebLogic Server JMS プロバイダか外部 JMS プロバイダであり、「ラッパーを使用するかどうか」で推奨されているラッパー手法を使用する場合は、ローカルではない JMS コンポーネントをコンフィグレーションするだけでなく、ローカルの JNDI ツリーで外部接続ファクトリと外部 JMS 送り先もコンフィグレーションする必要があります。
メッセージ駆動型 Bean を実装するには、次の手順を行います。
javax.ejb.MessageDrivenBean
インタフェースと javax.jms.MessageListener
インタフェースの両方を実装するソース ファイル (メッセージ駆動型 Bean クラス) を作成します。ejbCreate()
メソッドを 1 つ。onMessage()
メソッドを 1 つ。このメソッドには、メッセージを処理するビジネス ロジックが格納されます。 setMessageDrivenContext{}
を 1 つ。MDB もこのコンテキストを使用してコンテナのサービスにアクセスします。「メッセージ駆動型 Bean コンテキストの使用」を参照してください。ejbRemove()
メソッドを 1 つ。<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>,,,</ejb-name>
<ejb-class>...</ejb-class>
<transaction-type>Container</transaction-type>
<acknowledge-mode>auto_acknowledge</acknowledge-mode>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>Durable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>...</ejb-name>
<method-name>onMessage()</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
transaction-type
要素)。手順については、「MDB のトランザクション管理方式のコンフィグレーション」を参照してください。<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>exampleMessageDrivenA</ejb-name>
<message-driven-descriptor>
<pool>
<max-beans-in-free-pool>...</max-beans-in-free-pool>
<initial-beans-in-free-pool>...</initial-beans-in-free-pool>
</pool>
<destination-jndi-name>...</destination-jndi-name>
<initial-context-factory>...</initial-context-factory>
<provider-url> </provider-url>
<connection-factory-jndi-name>..<connection-factory-jndi-name>
<jms-client-id>.... </jms-client-id>
</message-driven-descriptor>
<jndi-name>someid</jndi-name>
<dispatch-policy>custom_execute_queue</dispatch-policy>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
コンフィグレーションする主要な要素は以下のとおりです。
weblogic-application.xml
で start-mdbs-with-application
を false
に設定します。このように設定することで、MDB は WebLogic Server が完全に起動するまでメッセージの処理を始めません。詳細については、「起動が完了するまでメッセージの処理を遅らせる」を参照してください。デプロイメント時に WebLogic Server で MDB の JMS 送り先を見つけることができない場合、デプロイメントは成功しますが、送り先が見つからなかったことを示すメッセージが WebLogic Server から出力されます。その場合、MDB は、JMS キューへの接続が成功するまで、定期的に接続を試行します。詳細については、「クラスタ化された MDB の移行と回復」を参照してください。
この節では、「MDB のプログラミングとコンフィグレーション : 主な手順」の手順を補足します。
注意 : MDB の主要なデプロイメント要素の概要については、「要約 : MDB のデプロイメント要素」を参照してください。
MDB がリスンする送り先のタイプは、ejb-jar.xml
の message-driven-destination
要素の destination-type
要素でコンフィグレーションします。
トピックを指定するには、destination-type
を javax.jms.Topic
に設定します。
キューを指定するには、destination-type
を javax.jms.Queue
に設定します。送り先がトピックの場合は、subscription-durability
を Durable
または NonDurable
のいずれかで指定します。詳細については、「恒久トピック サブスクリプションのコンフィグレーション」を参照してください。
MDB は独自にトランザクションを管理するか、トランザクション管理をコンテナに委ねることができます。
ejb-jar.xml
ファイルの message-driven
スタンザ内の transaction-type
要素を Container
に設定します。ejb-jar.xml
の container-transaction
スタンザの trans-attribute
要素を Required
に設定します。注意 : transaction-type
が Container
に設定されていて、trans-attribute
が設定されていない場合は、デフォルトの transaction-attribute
値 (MDB の場合は NotSupported
) が適用されます。WebLogic Server では、MDB をデプロイでき、準拠エラーをログに記録することもできます。ただし、このコンフィグレーション エラーを犯した場合、MDB はトランザクション的には実行されません。トランザクションの途中で障害が発生した場合、その障害の前に行われた更新はロールバックされません。
weblogic-ejb-jar.xml
の transaction-descriptor スタンザで trans-timeout-seconds を設定します。トランザクションがタイムアウトになると、そのトランザクションはロールバックされ、メッセージは再配信されます。デフォルトでは、トランザクションは 30 秒後にタイムアウトになります。トランザクションの時間が長いアプリケーションでは、タイムアウトの期間を長くする方がいいかもしれません。 ejb-jar.xml
ファイルの message-driven
スタンザ内の transaction-type
要素を Bean
に設定します。acknowledge-mode
要素を設定して、目的の JMS 確認応答を指定します (デフォルトの AUTO_ACKNOWLEDGE または DUPS_OK_ACKNOWLEDGE)。 詳細については、『WebLogic JMS プログラマーズ ガイド』の「Session オブジェクト」を参照してください。
WebLogic Server MDB は、Weblogic JMS 送り先と外部 (非 BEA) JMS プロバイダの送り先をサポートしています。
ローカル送り先とは、MDB と同じマシンまたは同じクラスタで動作する送り先のことです。リモート送り先とは、別のマシンで動作しており、MDB と同じクラスタのメンバーではない送り先のことです。送り先がローカルであるかリモートであるかは、その送り先と MDB が同じ JNDI コンテキストを共有しているかどうかに依存します。
お互いがお互いをローカルと見なすようにするには、MDB とその関連する JMS 送り先が両方とも同じマシン上、または同じ WebLogic Server クラスタ内で動作する必要があります。同じ WebLogic Server クラスタ内のサーバ インスタンス上の MDB と JMS 送り先は、それらが別々のマシン上にあってもお互いにローカルな存在です。WebLogic Server クラスタ内のサーバ インスタンスはそれぞれ同じクラスタワイドの JNDI ツリーのコピーを所有しているからです。
非 BEA の JMS プロバイダで動作する送り先は、「外部」と表現されます。外部 JMS プロバイダにはそれ専用の JNDI プロバイダがあり、外部 JMS オブジェクトは WebLogic Server MDB と同じコンテキストを共有しません (外部 JMS オブジェクトがラッパーを使用して MDB の JNDI コンテキストに含まれるようにコンフィグレーションされていない限り)。その手法については、「ラッパーを使用するかどうか」を参照してください。
送り先の性質 (ローカルかリモートか、WebLogic JMS か非 BEA か) は利用可能なコンフィグレーション オプションを決め、weblogic-ejb-jar.xml
の MDB の message-driven-descriptor の以下の主要な要素のコンフィグレーション方法をある程度まで決定します。
外部でリモートの送り先の場合、もっともシンプルなコンフィグレーション方式は WebLogic Server JMS ラッパーを使用することです。ラッパーを使用すると、サードパーティ JNDI プロバイダあるいは別の WebLogic Server クラスタまたはドメインの JMS オブジェクトとローカル WebLogic JNDI ツリーのオブジェクトの間に「シンボリック リンク」を作成できます。
ラッパーをいつ使うのか、および weblogic-ejb-jar.xml
で message-driven-descriptor
をコンフィグレーションするルールの詳細については、以下の節を参照してください。
特定のシナリオで message-driven-descriptor
の要素をコンフィグレーションするには、「一般的な送り先のシナリオ : イラストと主な要素の設定」を参照してください。
ラッパーを使用するということは、リモート JMS オブジェクト (非 BEA または WebLogic JMS) に対応する外部接続ファクトリおよび外部送り先をローカル JNDI ツリーのエントリとしてコンフィグレーションするということです。
ラッパー クラスを使用するかどうかで、以下に説明するように initial-context-factory
と destination-jndi-name
のコンフィグレーション方法が決まります。
provider-url は、MDB がリスンする送り先の JMS プロバイダで使用される JNDI サービスの URL を指定します。
provider-url
を指定しないでください。initial-context-factory は、JMS プロバイダで使用される初期コンテキスト ファクトリを実装するクラスを指定します。
destination-jndi-name は、MDB がリスンする送り先の JNDI 名を指定します。
connection-factory-jndi-name は、JMS プロバイダで使用される接続ファクトリの JNDI 名を指定します。
connection-factory-jndi-name
を指定しないでください。 カスタム接続ファクトリは、デフォルトの WebLogic Server 接続ファクトリではアプリケーションの要件を満たせない場合に使用します。たとえば、MessagesMaximum
属性で特定の必要な値を指定するためにカスタム接続ファクトリをコンフィグレーションする場合もあります。接続ファクトリのコンフィグレーション手順については、Administration Console オンライン ヘルプの「JMS 接続ファクトリのコンフィグレーション」を参照してください。
注意 : MDB のカスタム JMS 接続ファクトリをコンフィグレーションする場合は、必ず Acknowledge Policy
属性を Previous
に設定し、UserTransactionsEnabled
属性が有効であるようにしてください。
この節の図は、一般的な送り先のコンフィグレーションを示しています。リモートおよび外部の送り先については、ラッパー「あり」と「なし」のシナリオが用意されています。
表 7-1 は、各シナリオの weblogic-ejb-jar.xml
の message-driven-descriptor
スタンザ内の要素のコンフィグレーション方法を示しています。
図 7-7 A. ローカル WebLogic JMS サーバの送り先
図 7-8 B. リモート WebLogic JMS サーバの送り先 (ラッパーなし)
図 7-9 C. 外部 JMS サーバの送り先 (ラッパーなし)
図 7-10 D. リモート WebLogic Server または外部 JMS サーバの送り先 (ラッパーあり)
恒久サブスクリプションを使用すると、MDB はその MDB が接続されていないときにトピックに配信されたメッセージを受信できます。
クラスタ化されていないサーバ インスタンスにデプロイされた MDB で恒久トピック サブスクリプションをコンフィグレーションするには、次の手順を行います。
Administration Console オンライン ヘルプの「JMS 接続ファクトリのコンフィグレーション」の説明にしたがって、アプリケーションの特定の要件に合わせて独自の接続ファクトリをコンフィグレーションする場合は、接続ファクトリをコンフィグレーションするときに MDB の ClientID
を定義できます。
接続ファクトリを設定してもそれに ClientID
を割り当てないか、デフォルトの接続ファクトリを使用する場合 (Administration Console オンライン ヘルプの「デフォルト接続ファクトリの使い方」を参照)、MDB は weblogic-ejb-jar.xml
の jms-client-id の値をクライアント ID として使用します。jms-client-id
が指定されていない場合、デフォルト値は MDB の ejb-name です。
クラスタでは、JMS 恒久サブスクリプションは MDB の以下の ID の組み合わせでユニークに識別されます。
ClientId
であり、クラスタ内でユニークです。jms-client-id
。サブスクリプション ID はそのトピックでユニークでなければならないので、恒久トピック サブスクリプションのある MDB はクラスタ内の複数のサーバ インスタンスで実行できません。MDB の最初のインスタンスがクラスタ内のサーバ インスタンスで起動した後、MDB の追加インスタンスを別のクラスタ化されたサーバに正常にデプロイできますが、MDB が起動すると衝突が検出され、MDB のそのインスタンスは JMS に完全には接続できません。恒久サブスクライバ MDB をクラスタ内の複数のサーバ インスタンスで実行できるようにするには (各 MDB インスタンスが各トピック メッセージのコピーを受信する)、各 MDB インスタンスをユニークな jms-client-ID
でデプロイする必要があります (jms-client-ID
が指定されていない場合は ejb-name
)。
恒久サブスクライバは WebLogic Server の分散送り先トピックを直接サブスクライブできませんが、代わりに送り先トピックの物理メンバーの JNDI 名をサブスクライブする必要があります。そのようにするには、以下の 2 通りの方法があります。
destination-jndi-name
で各恒久サブスクライバ MDB プールをコンフィグレーションする。またはJNDINameReplicated
属性を false
に設定する。詳細については、Administration Console オンライン ヘルプの「[JMS トピック] --> [コンフィグレーション] --> [一般]」を参照。以下のトピックでは、メッセージの配信に関連する動作のガイドラインを示します。
MDB のビジネス ロジックが非同期のメッセージ処理に対応できるようにしておきます。MDB は必ずしも、クライアントが発行した順序でメッセージを受信するわけではありません。受信順序がクライアントのメッセージ送信順序と一致するようにするには、以下を行います。
トランザクションのロールバックと回復の時にメッセージの順序付けを守るには、カスタム接続ファクトリを値 1 の MessagesMaximum
でコンフィグレーションし、再配信遅延がコンフィグレーションされないようにします。詳細については、『WebLogic JMS プログラマーズ ガイド』の「メッセージの再配信の順序付け」を参照してください。
詳細については、Interface MessageListener (javax.jms.MessageListener.onMessage()
) に関する Sun のドキュメントを参照してください (http://java.sun.com/j2ee/sdk_1.2.1/techdocs/api/javax/jms/MessageListener.html/)。
JMS プロバイダは、MDB が受信メッセージの確認応答をするのを待ち受けます。MDB がメッセージを受信したが、確認応答の送信に失敗した場合、JMS プロバイダは同じメッセージを再送信します。
MDB の設計は、重複メッセージの可能性を考慮に入れているはずです。重複メッセージは、特定の状況では有害になります。たとえば、MDB の onMessage()
メソッドに銀行口座の借方に記入するコードが含まれている場合、そのメッセージを 2 回受信して処理すると借方への記入が 2 回行われることになります。また、メッセージが再送信されると、処理リソースがより多く消費されることになります。
重複メッセージの配信を防止する最適な方法は、コンテナ管理によるトランザクションを使用することです。コンテナ管理によるトランザクションでは、トランザクションの中でメッセージの受信と確認応答が行われます (つまり両方行われるか、両方とも行われない)。ただし、これは Bean 管理のトランザクションを使用するよりも信頼性が高くなりますが、パフォーマンスは犠牲になります。コンテナ管理によるトランザクションでは、より多くの CPU リソースとディスク リソースが使用されるからです。
MDB がそれ自身のトランザクションを管理する場合は、受信と確認応答がトランザクションの外で行われるので、onMessage()
のコードで重複メッセージを処理する必要があります。一部のアプリケーションは、重複メッセージの受信と処理に対応しています。上の銀行口座のシナリオのような他のケースでは、トランザクションが Bean 管理の場合は、Bean のコードで重複メッセージの処理を防止する必要があります。たとえば、MDB ではデータベースですでに消費されているメッセージを追跡できます。
MDB の onMessage()
メソッドが正常に完了する場合でも、OnMessage()
の完了とコンテナによるメッセージ配信の確認応答の間にサーバがクラッシュすると、MDB は重複メッセージを受信することになります。図 7-11 は、そのシナリオを示しています。
図 7-11 onMessage() の完了とコンテナによる配信の確認応答の間のサーバ クラッシュ
MDB がメッセージを消費している最中に予期しないエラーが発生した場合、MDB はシステム例外を送出できます。その例外により、JMS のコンフィグレーションに応じて JMS は再送信、遅延後に再送信、または放棄を行います。
トランザクション MDB でメッセージの再配信を強制するには、Bean のコンテキストを使用して setRollbackOnly()
を使用します。
トランザクション対応かどうかに関係なく、MDB でメッセージの再配信を強制するには、MDB によって送出される RuntimeException または Error から派生した例外を送出できます。このようにすると、MDB インスタンスは破棄および再作成され、パフォーマンスの低下につながります。
再配信遅延は、MDB の onMessage()
メソッドが実行するタスクの種類に基づいてコンフィグレーションします。場合によっては、たとえばニュース サービスに速報を流すアプリケーションなどで、再配信は即時に行うことが必要にあります。その他の場合、たとえばデータベースのダウンが原因で MDB が例外を送出する場合、再配信はデータベースが復帰した後でない限りすぐでなくてもかまいません。
注意 : 正確に順序付けされている MDB の場合は、再配信遅延を設定しないでください。
再配信遅延と、MDB で使用できる他の JMS 例外処理機能のコンフィグレーション手順については、『WebLogic JMS プログラマーズ ガイド』の「ロールバック、回復、再配信、または期限切れメッセージの管理」を参照してください。
WebLogic Server は、setMessageDrivenContext()
を呼び出して MDB インスタンスとコンテナ コンテキストを関連付けます。これはクライアント コンテキストではありません。クライアント コンテキストは、JMS メッセージと一緒には渡されません。
MDB インスタンス内からコンテナ コンテキストのプロパティにアクセスするには、MessageDrivenContext
インタフェースの以下のメソッドを使用します。
getCallerPrincipal())
- EJBContext
インタフェースからの継承であり、MDB インスタンスから呼び出してはなりません。isCallerInRole()
- EJBContext
インタフェースからの継承であり、MDB インスタンスから呼び出してはなりません。setRollbackOnly()
- コンテナ管理によるトランザクションを使用する EJB でのみ使用できます。getRollbackOnly()
- コンテナ管理によるトランザクションを使用する EJB でのみ使用できます。getUserTransaction()
- Bean 管理によるトランザクションの境界設定を使用する EJB でのみ使用できます。注意 : getEJBHome()
も MessageDrivenContext
インタフェースの一部として継承されますが、メッセージ駆動型 Bean にはホーム インタフェースがありません。MDB のインスタンスから getEJBHome()
を呼び出すと、IllegalStateException
が送出されます。
デフォルトでは、対象の WebLogic Server インスタンスが完全に起動していなくても、MDB はそのデプロイメントと同時にメッセージの処理を開始します。このため、MDB アプリケーションは起動プロセスの途中で初期化されていないサービスやアプリケーションにアクセスし、失敗することがあります。この問題が起きないようにするには、weblogic-application.xml
で start-mdbs-with-application
を false
に設定します。
start-mdbs-with-application
を false
に設定すると、サーバの起動プロセスの終わり近く、サーバ インスタンスがそのリスン ポートを開いた後まで処理の開始が強制的に延期されます。
メッセージ駆動型 Bean (MDB) が JMS キューまたはトピックからメッセージを受信すると、EJB コンテナは資格マッピング プロバイダおよび資格マップを使用して、JMS 接続の確立時に使用するセキュリティ ID (ユーザ名とパスワード) を取得します。この資格マッピングは、MDB の起動時に一度だけ行われます。
EJB コンテナが一度接続されると、JMS プロバイダは確立されたセキュリティ ID を使用してすべてのメッセージを受信します。
MDB のセキュリティ ID をコンフィグレーションするには、次の手順を行います。
<security-role-assignment>
<role-name>admin</role-name>
<principal-name>username
</principal-name>
</security-role-assignment>
注意 : JMS プロバイダが WebLogic JMS の場合は、資格マッパーをコンフィグレーションする必要はありません。
WebLogic Server は、クラスタ化されている MDB アプリケーションの移行と回復をサポートしています。障害が発生した場合には、JMS 送り先と MDB をオンラインに戻すことができます。アプリケーションは、サーバ インスタンスで障害が発生したときに、クラスタ内の障害の発生したサーバから利用可能なサーバ インスタンスへ自動的に JMS 送り先とその関連 MDB を移行するように設計する必要があります。
注意 : MDB は、クラスタ化されたサーバとの間でのみ移行可能サービスを使用できます。移行可能サービスは、複数のクラスタにまたがって使用することはできません。
別のサーバに移行した後、MDB アプリケーションは移行された JMS 送り先に再接続し、JMS 送り先から再びメッセージの受信を開始します。
MDB には、移行可能な対象はありません。代わりに、MDB はデプロイメント時に自動的に JMS サーバの移行先を検出し、それを移行可能の対象として利用します。MDB は、JMS サーバがデプロイされるすべての場所にデプロイされるようにする必要があります。それは、次の 2 つの方法で行うことができます。
config.xml
にある JMS 移行可能対象リストに MDB の対象を一致させる。MDB の対象サーバの名前が JMS の移行可能対象リストと一致しない場合、MDB の移行は失敗します。移行可能な対象のコンフィグレーションの詳細については、『WebLogic Server クラスタ ユーザーズ ガイド』の「クラスタ内の移行可能対象サーバの定義」を参照してください。図 7-12 で、管理対象サーバ 1、2、および 3 は同じクラスタの中にあります。管理対象サーバ 2 と管理対象サーバ 3 は、管理対象サーバ 1 の移行可能な対象としてコンフィグレーションされています。管理対象サーバ 1 で障害が発生すると、JMS 送り先と MDB が次に利用可能な管理対象サーバに移行します。対象リストの管理対象サーバが利用できない場合、送り先と MDB は対象リストの次に利用可能な管理対象サーバに移行します。たとえば、管理対象サーバ 2 が管理対象サーバ 1 の障害時に利用できない場合、JMS 送り先と MDB アプリケーションは管理対象サーバ 3 に移行します。
移行可能サービスの実装手順、およびクラスタ化されたアーキテクチャの WebLogic JMS の移行サービスおよび回復サービスの背景情報については、『WebLogic JMS プログラマーズ ガイド』の「クラスタ内での移行可能なサービスとしての JMS」を参照してください。
この節では、MDB の動作に影響する主なデプロイメント要素をリストします。
表 7-2 は、weblogic-ejb-jar.xml
の message-driven-descriptor スタンザのデプロイメント要素をまとめたものです。
表 7-3 は、weblogic-application.xml
の ejb
スタンザの MDB の主なデプロイメント要素のリストです。
表 7-4 は、ejb-jar.xml
の message-driven
スタンザでコンフィグレーションする MDB の主な J2EE デプロイメント要素のリストです。
表 7-2 weblogic-ejb-jar.xml の MDB のデプロイメント要素
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
表 7-3 weblogic-application.xml の MDB の要素
|
|
||
|
||
|