Oracle® Fusion Middleware Oracle WebLogic Server JMS プログラマーズ ガイド 11g リリース 1 (10.3.1) B55536-01 |
|
![]() 戻る |
![]() 次へ |
以下の節では、メッセージ順序単位を使用して、WebLogic JMS の使用時に厳格なメッセージ順序を提供する方法について説明します。
メッセージ順序単位は WebLogic Server の付加価値機能です。スタンドアロンのメッセージ プロデューサや、単体として動作するプロデューサのグループは、この機能を使用して複数のメッセージを処理順序に応じた 1 つの単位にグループ化できます。この単位を順序単位と呼び、この単位からのすべてのメッセージはその作成順に従って処理されます。
以下の節では、JMS 仕様に記述されているメッセージ処理と、WebLogic Server のメッセージ順序単位機能を使用して拡張したメッセージ処理を比較します。
Java Message Service 仕様 (http://www.java.sun.com/products/jms/docs.html
) ではメッセージ配信の順序付けが規定されていますが、この順序付けは非常に厳格に適用されます。プロデューサの単一のインスタンスとコンシューマの単一のインスタンスの間の順序が定義されますが、以下のような一般的な状況は考慮されていません。
1 つのキューに多数のコンシューマが存在する (「分散送り先の使用」を参照)。
単一のプロデューサとして動作する単一のアプリケーション内に複数のプロデューサが存在する (「分散送り先の使用」を参照)。
メッセージの回復やトランザクションのロールバック。これらの場合、同じプロデューサからの別のメッセージが、他のコンシューマに配信されて処理される可能性があります (「処理中にメッセージが遅延した場合の処理」を参照)。
フィルタおよび送り先ソート キーの使用 (「メッセージ順序単位の高度なトピック」を参照)。
メッセージ順序単位機能を使用すると、メッセージ プロデューサや単体として動作するプロデューサのグループが、複数のメッセージを 1 つの単位にグループ化してメッセージを作成順に処理することが可能になります。単一のメッセージのメッセージ処理は、メッセージが確認応答、コミット、回復、またはロールバックされたときに完了します。メッセージのメッセージ処理が完了するまでは、その順序単位の残りの未処理メッセージがブロックされます。
この節では、順序単位を使用した場合の JMS 確認応答モード (http://www.java.sun.com/products/jms/docs.html
) の規則について説明します。
確認応答モードが CLIENT_ACKNOWLEDGE
、AUTO_ACKNOWLEDGE
、または DUPS_OK_ACKNOWLEDGE
である場合、順序単位のメッセージは並行処理されません。
コンシューマをクローズすると、セッションの確認応答に関係なく、現在のメッセージ処理が完了します。
CLIENT_ACKNOWLEDGE
- アプリケーションが Message.acknowledge
および Session.recover
を呼び出すと、順序単位内でどのメッセージの処理が完了したかが示されます。
AUTO_ACKNOWLEDGE
- receive
の呼び出しからセッションが正常に返されたとき、または呼び出された MessageListener
からセッションが正常に返されたときに、セッションが自動的にクライアントによるメッセージの受信を確認応答します。
非同期モード : 正常な完了または onMessage(msg)
の例外は、メッセージが正常に処理されたタイミングを示します。
同期モード : 特定のコンシューマ (たとえばコンシューマ A) では、consumerA.receive
、consumerA.setMessageListener
、または consumerA.close
が発生したときに consumerA.receive
が完了します。
DUPS_OK_ACKNOWLEDGE
- receive
の呼び出しからセッションが正常に返されたとき、または呼び出された MessageListener
からセッションが正常に返されたときに、セッションが自動的にクライアントによるメッセージの受信を確認応答します。
非同期モード : 正常な完了または onMessage(msg)
の例外は、メッセージが正常に処理されたタイミングを示します。
同期モード : 特定のコンシューマ (たとえばコンシューマ A) では、consumerA.receive()
、consumerA.setMessageListener()
、または consumerA.close()
が発生したときに consumerA.receive()
が完了します。
NO_ACKNOWLEDGE
- セッションは、処理の順序を保証しません。メッセージは、使用可能な別のコンシューマで並行処理できます。
メッセージ順序単位では、以下の規則に従ってメッセージが配信されます。
順序単位のメンバー メッセージは、作成された順番でキュー コンシューマに配信される。順序単位内でのメッセージの順序は、ソート条件、優先順位、およびフィルタには影響されません。ただし、未コミットのメッセージに Redelivery Delay
または期限切れになっていない TimetoDeliver
タイマーが設定されている場合は、それ以降のメッセージが遅延します。
順序単位メッセージは、一度に 1 つずつ処理される。1 つのメッセージの処理が完了したら、順序単位内の次のメッセージが配信されます。
分散キューに送信された順序単位メッセージは、分散キューの 1 つの物理メンバー上にのみ存在する。詳細については、「分散送り先で順序単位を使用する」を参照してください。
同じ順序単位からの未コミットまたは未応答のメッセージはすべて、同じトランザクション (トランザクション非対応の場合は同じ JMSSession
) に存在しなければならない。順序単位内の 1 つのメッセージが未コミットまたは未応答である場合、他のメッセージは同じトランザクションまたは JMSSession
にのみ配信されます。これにより、同じ順序単位からのすべての未応答メッセージが 1 つの回復可能な処理内に保持され、ロールバックや回復に関係なく順序を維持できます。
キューに同じ順序単位からの複数のメッセージがある場合、それらがすべて処理されるまでは、そのキューに次のメッセージを配信したり、キュー コンシューマにそれらのメッセージを配信したりすることはできない。
たとえば、メッセージが M1 から Mn まであるとします。
これらのメッセージがトランザクションの一部として配信され、そのトランザクションがロールバックされた (処理が完了した) 場合、メッセージ M1 から Mn が使用可能なコンシューマに配信されます。
これらのメッセージがトランザクション外で配信されて回復された (処理が完了した) 場合、メッセージ M1 から Mn が使用可能なコンシューマに配信されます。
これらのメッセージがトランザクション外で配信されて確認応答された (処理が完了した) 場合、未配信のメッセージ Mn+1 が使用可能なコンシューマに配信されます。
この節では、オンライン書店への本の注文に基づいて、メッセージ順序単位の単純なケース スタディを行います。
XYZ オンライン書店は、JMS を使用して顧客の注文を処理する単純な処理設計を実装しています。JMS 処理システムは、以下から構成されます。
キュー (Queue1) に送信するメッセージ プロデューサ
Queue1 からのメッセージを処理する複数のメッセージ駆動型 Bean (MdbX、MdbY など)
注文および注文のステータス情報を格納するデータベース (myDB)
Joe は、XYZ オンライン書店の自分のアカウントにログインして欲しい本を検索します。本を選び、会計に進んで、販売トランザクションを完了します。ここで Joe は、以前に同じ本を買っていたことに気付き、注文をキャンセルします。ところが 1 週間後、その本が Joe のもとに届いてしまいます。
Joe の注文シナリオでは、注文キャンセル メッセージが、注文メッセージよりも前に処理されました。その結果、買いたくなかった本が届けられてしまいました。ここでは、Joe の注文が処理された手順について説明します。
次の図とそれに対応する各アクションは、Joe の注文がどのように処理されたかを示します。
Joe が、ショッピング カートから注文ボタンをクリックします。
注文メッセージ (メッセージ A) が Queue1 に配置されます。
Joe が注文をキャンセルします。
注文キャンセル メッセージ (メッセージ B) が Queue1 に配置されます。
MdbX が Queue1 からメッセージ A を取得します。
MdbY が Queue1 からメッセージ B を取得します。
MdbY がキャンセル メッセージをデータベースに書き込みます。対応する注文メッセージがないため、どの注文メッセージもデータベースから削除されません。
MdbX が注文メッセージをデータベースに書き込みます。
本の発送を処理するアプリケーションがデータベースを読み取り、注文メッセージを見て Joe の家への発送を開始します。
Java Message Service 仕様 (http://www.java.sun.com/products/jms/docs.html
) にはメッセージ配信の順序付けが規定されていますが、プロデューサの単一のインスタンスとコンシューマの単一のインスタンスの間でのメッセージ配信の順序付けしか規定されていません。Joe のケースでは、Queue1 のメッセージを複数のメッセージ駆動型 Bean (MDB) が消費できるため、メッセージの処理順序はまったく保証されなくなっていました。
Joe の注文に関わるすべてのメッセージが常に正しく処理されるようにするには、XYZ 書店のシステム管理者がユーザ セッションに基づいてメッセージ順序単位をコンフィグレーションして、ユーザ セッションからのすべてのメッセージに順序単位名属性を持たせ、値としてセッション ID を設定します。「順序単位の作成方法」を参照してください。WebLogic Server では順序単位内のメッセージが並行処理されることはないため、Joe のユーザ セッションの間に作成されたすべてのメッセージは作成された順番どおりに処理されます。
次の図とそれに対応する各アクションは、メッセージ順序単位を使用した場合に Joe の注文がどのように処理されるかを示します。
Joe が、ショッピング カートから注文ボタンをクリックします。
注文メッセージ (メッセージ A) が Queue1 に配置されます。
Joe が注文をキャンセルします。
注文キャンセル メッセージ (メッセージ B) が Queue1 に配置されます。
MdbX が Queue1 からメッセージ A を取得します。
MdbY が Queue1 からメッセージ B を取得します。
MdbY のメッセージ B は、MdbX が注文メッセージを応答確認するまではブロックされます。「処理中にメッセージが遅延した場合の処理」を参照してください。
メッセージ A がコミットされ、データベースに書き込まれます。
メッセージ B がコミットされ、データベースに書き込まれます。
対応する注文メッセージが存在するため、Joe の注文はデータベースから削除され、本が届けられることはありません。
以下の節では、メッセージ順序単位を作成する方法について説明します。「順序単位によるメッセージ配信」および「メッセージ順序単位の高度なトピック」も参照してください。
WLMessageProducer
インタフェースの setUnitOfOrder()
メソッドを使用して、プロデューサを順序単位名に関連付けます。
次の例では、順序単位名属性の値が myUOOname に設定されます。
getProducer().setUnitOfOrder("myUOOname");
プロデューサを順序単位名に関連付けると、プロデューサをクローズするか、プロデューサと順序単位の関連付けが解消されるまで、このプロデューサが送信するすべてのメッセージは順序単位として処理されます。
次のコードでは、プロデューサと順序単位の関連付けの例を示します。
ここでは、JMS 接続ファクトリや JMS 送り先をコンフィグレーションして、メッセージ順序単位を有効にする方法について説明します。
以下のいずれかの方法で、JMS 接続ファクトリと送り先をコンフィグレーションしてメッセージ順序単位を有効にします。
接続ファクトリをコンフィグレーションして、常にユーザ生成の順序単位名を使用するようにする。この場合、その接続ファクトリから作成されたすべてのプロデューサで順序単位が有効化されます。Oracle Fusion Middleware Oracle WebLogic Server の Administration Console オンライン ヘルプの「接続ファクトリの順序単位パラメータのコンフィグレーション」を参照してください。
接続ファクトリをコンフィグレーションして、セッションごとに常にシステム生成の順序単位名を使用するようにする。Oracle Fusion Middleware Oracle WebLogic Server の Administration Console オンライン ヘルプの「接続ファクトリの順序単位パラメータのコンフィグレーション」を参照してください。
クライアントから WLProducer.setUnitOfOrder(name)
を呼び出して、プロデューサの接続ファクトリの初期設定を変更する。
スタンドアロンの送り先または分散送り先をコンフィグレーションして、常にシステム生成の順序単位名を使用するようにする。Administration Console オンライン ヘルプの以下のトピックを参照してください。
従来の JMS アプリケーションと相互運用する場合には、接続ファクトリまたは送り先に管理的に順序単位をコンフィグレーションする必要があります。この方法は、コードを変更することなく、メッセージが作成順に処理されるようにするための単純なメカニズムを提供します。
順序単位は、名前属性によって特定されます。送り先内では、順序単位名属性に同じ値が設定されているメッセージが、同じ順序単位に属します。名前は、システムからでもアプリケーションからでも指定できます。同じ順序単位内のすべてのメッセージは、同じ名前を共有します。「順序単位の作成方法」を参照してください。
順序単位の名前属性は、以下の規約に準拠させる必要があります。
順序単位名属性の有効な値は、null でも空でもない文字列でなければならない。
システム生成の順序単位名は、タイムスタンプ ベースで統計的にユニークになる。
アプリケーションからは、独自の順序単位名を指定できる。たとえば、WebLogic Integration アプリケーションではワークフロー名を使用したり、Web サービス アプリケーションでは会話名を使用したりできます。
メッセージ順序単位には、独自のネームスペースがある。順序単位は、他の名前付きオブジェクトに対してユニークにする必要はありません。たとえば、Foo というキューが存在する場合でも、Foo という順序単位名は有効です。
メッセージ順序単位のスコープは、単一の送り先に限定される。2 つの送り先のそれぞれの順序単位を同じ名前にしても構いません。
1 つまたは複数のプロデューサが、同じ文字列を使用して順序単位を作成することで、同じ順序単位名のメッセージを送信できる。順序単位名は、配信されたメッセージから抽出されます。次に例を示します。
msg.getStringProperty("JMS_BEA_UnitOfOrder");
したがって、システム生成の順序単位名は、複数のプロデューサで使用できます。このパラダイムは、アプリケーションによって割り当てられた順序単位名にもそのまま適用できます。情報が一元的にシリアライズされているのが最も効率的です。したがって、順序単位名としては会話 ID のようなプロパティのみを格納するようにしてください。このパラダイムは、メッセージが順序単位非対応の JMS プロバイダ (WebLogic 9.0 より前のリリースや WebLogic 以外の JMS プロバイダ) で送信された場合には適用されません。
以下の節では、より高度で複雑な状況での順序単位によるメッセージ処理方法について説明します。
メッセージ処理の間には、通常であればメッセージの処理順序が変更されるような状況が数多く発生します。以下に、メッセージの配信準備を整えることができない典型的なメッセージ処理状態を示します。
メッセージを含むトランザクションがコミットされていない
メッセージの TimeToDeliver
値が設定されており、TimeToDeliver
間隔が経過するまではメッセージを配信できない
コンシューマが回復またはロールバックを呼び出したため、RedeliveryDelay
間隔が経過するまではメッセージを再配信できない
たとえば、メッセージ A とメッセージ B が同じ順序単位に届き、上に挙げたような状況でメッセージ A を配信できないとします。この場合、メッセージ B の配信を遅延させる要因がなくても、順序単位内のメッセージ A が配信されるまではメッセージ B を配信することはできません。
フィルタと順序単位を使用すると、予期しない動作が発生することがあります。たとえば、メッセージ A から Z が、同じキューの同じ順序単位にあるとします。Consumer1 にはフィルタが設定されており、メッセージ A、B、および C がそのフィルタ条件を満たすため、これらのメッセージが Consumer1 に配信されます。
メッセージ D から Z は、メッセージ A、B、および C が確認応答されるまでは配信できません。
メッセージ A、B、および C が確認応答または回復されます。
メッセージ D がメッセージ配信システムから利用可能な状態になります。
メッセージ D はフィルタ条件を満たさないため、Consumer1 に配信されることはありません。
メッセージ E から Z は、メッセージ D が処理されるまでは配信できません。
メッセージ D を含むトランザクションは、ロールバックされる必要があります。
メッセージ D が処理されると、メッセージ E から Z を配信できます。
詳細については、「メッセージのフィルタ処理」を参照してください。
送り先ソート キーは、メッセージが順序単位の一部でない場合や、同じ順序単位の一部でない場合に、コンシューマにメッセージを配信する順序を制御します。
たとえば、届いたメッセージ A および B がキュー上の同じ順序単位に含まれており、優先度の降順でソートされていて優先度はメッセージ A よりメッセージ B のほうが高いとします。
メッセージ B のほうがメッセージ A よりも優先度が高くても、これらのメッセージは同じ順序単位に含まれているため、メッセージ A が処理されるまではメッセージ B を配信できません。次に届いたメッセージ C は、順序単位が設定されていないか、メッセージ A と同じ順序単位には含まれていないとします。この場合、メッセージ C の優先度設定とメッセージ A の優先度設定によって配信順序が決まります。『Oracle Fusion Middleware Oracle WebLogic Server JMS のコンフィグレーションと管理』の「基本 JMS システム リソースのコンフィグレーション」を参照してください。
すでに「JMS 仕様に準拠したメッセージ処理」で説明したように、アプリケーションで分散キューを使用している場合、Java Message Service 仕様 (http://www.java.sun.com/products/jms/docs.html
) のメッセージ配信の順序付けは保証されません。WebLogic JMS では、分散送り先が対象指定されている複数のメッセージに同じ順序単位が設定されている場合は、それらのメッセージを同じ分散送り先メンバーに転送します。メンバーは、送り先の順序単位コンフィグレーションに基づいて選択されます。
WebLogic パス サービスをコンフィグレーションすると、順序単位に含まれるメッセージをその送り先リソース (共通分散送り先のメンバー) にルーティングするために必要な情報を格納する永続マップを提供できます。共通分散送り先の WebLogic パス サービスがコンフィグレーションされていない場合、メンバー送り先へのルーティング パスは、分散キューの実行時のロード バランシング ヒューリスティックに基づいて決定されます。
WebLogic パス サービスがコンフィグレーションされていない場合、メンバー キューへのデフォルトのルーティング パスは、メッセージ順序単位名と共通分散キュー メンバーのハッシュ コードに基づいて選択されます。このルーティング メカニズムの利点は、分散キュー メンバーへのルートがすばやく計算され、クラスタ内の永続ストレージを必要としない点です。
メッセージ順序単位とハッシュ ベースのルーティングを実装する際には、以下のことに留意してください。
順序単位が関連付けられている分散キュー メンバーが分散キューから削除されると、新しいメッセージは別の分散キュー メンバーに送信され、古いメッセージとそのメッセージとの継続性は失われる。
順序単位が関連付けられている分散キュー メンバーにアクセスできない場合は、メッセージを送信しているプロデューサが JMSOrderException
を送出し、メッセージは別の分散キュー メンバーにはルーティングされない。この例外が送出されるのは、JMS メッセージ システムが必要なサービス品質を満たすことができないからです。特定の順序単位に対しては、1 つの分散送り先メンバーだけがメッセージを消費できます。
メッセージ順序単位を使用して、共通分散送り先でのパス サービスまたはハッシュ ベースのルーティング メカニズムをコンフィグレーションする場合は、以下のトピックのいずれかを参照してください。
Oracle Fusion Middleware Oracle WebLogic Server の Administration Console オンライン ヘルプの「共通分散トピック - 詳細パラメータのコンフィグレーション」
Oracle Fusion Middleware Oracle WebLogic Server の Administration Console オンライン ヘルプの「共通分散キュー - 詳細パラメータのコンフィグレーション」
順序単位を割り当てても、同じトピック上の 2 つのサブスクライバによるメッセージの並行処理は可能です。トピックの個々のサブスクライバには独自の送り先とメッセージ リストがあるため、コンシューマが 1 つのキューと同様に、メッセージはプロダクション時に割り当てられた順序単位に従ってすべてのサブスクライバによって処理されます。
アプリケーションが分散トピックのメンバーに直接送信を行う場合、物理的トピック間のメッセージのルーティングが、順序単位に影響を与える可能性があります。処理の順序が正しくなるようにするには、メッセージが論理分散トピックを介して送信される (つまり、送り先が分散トピックの JNDI 名を使用して取得される) ことをアプリケーションで保証する必要があります。その結果、WebLogic Server では、同じ順序単位を持つメッセージであれば、その分散トピック メンバーへのパスが同じであることが保証されます。
WebLogic Server メッセージ駆動型 Bean の実装は、単一のトピック サブスクリプションおよび JMS セッションの着信メッセージ ストリームの並行処理を可能にするため、EJB および JMS 仕様の要件に準拠していません。この並行処理では、順序単位は考慮されないため、処理が正しく順序付けられていることを保証する必要があります。正しく順序付けするには、2 つの方法があります。1 つは各メッセージをそれ専用の JTA トランザクション内で処理する方法で、もう 1 つはプール サイズを 1 に設定して並行処理を無効にする方法です。
トピックおよびメッセージ駆動型 Bean で順序単位を使用する場合は、以下のいずれかを行う必要があります。
まず、JTA トランザクションを使用するよう MDB をコンフィグレーションします。万一トランザクションのオーバーヘッドが許容できない場合は、プール サイズを 1 に設定します。
最も簡単な方法は、JTA トランザクションを使用することです。この方法は、処理オーバーヘッドが生じますが、WebLogic Server には高度に最適化されたトランザクション エンジンが存在するため通常は低く抑えられ、アプリケーションは順序単位が異なるメッセージを並行処理することでメリットを得ることができます。アプリケーションの使用例によっては、JTA トランザクションが有効な場合があります。たとえば、JMS メッセージの送信やデータベースの更新など、他の操作との原子性を維持した相互作用を保証することが必要な場合です。
プール サイズを 1 に設定すると、より効率的な非トランザクション メッセージングを使用できますが、並行処理では非常に大きな効果をもたらします。
JMS メッセージ管理を使用すると、JMS の管理者は実行中の JMS サーバ内のほとんどのメッセージを移動したり削除したりできます。つまり、管理者は「順序単位によるメッセージ配信」に示した配信規則を侵害することができます。
たとえば、順序単位 foo に属すメッセージ A、B、C、および D が生成されて送り先 D1 に送信された場合、以下の点に留意してください。
メッセージ C および D を送り先 D2 に移動すると、両方の送り先からのメッセージが並行して処理される可能性がある。
メッセージ B および C を送り先 D2 に移動すると、メッセージ A とメッセージ B および C が並行して処理される可能性がある。メッセージ A が処理された後に、メッセージ D が配信可能になる。
メッセージ順序の維持に依存するアプリケーションでは、1 つの順序単位内のすべてのメッセージを単一のグループとして移動するのがベスト プラクティスです。
順序単位の配信規則が維持されるようにするには、次の手順に従ってください。
ソース送り先と対象送り先を休止させます。
移動する順序単位内のすべてのメッセージを選択します。
選択したメッセージを対象送り先に移動します。必要に応じて、メッセージを処理したい順序にソートします。
ソース送り先と対象送り先を再開します。
詳細については、『Oracle Fusion Middleware Oracle WebLogic Server JMS のコンフィグレーションと管理』の「WebLogic JMS のトラブルシューティング」を参照してください。
WebLogic ストア アンド フォワードでは、メッセージ順序単位がサポートされます。たとえば、Foo という順序単位のメッセージを送信するストア アンド フォワード プロデューサがあるとします。このプロデューサは、切断して別の接続で再接続すると、Foo という順序単位を作成してメッセージの送信を継続します。再接続の前と後に送信されたすべてのメッセージは、同じストア アンド フォワード エージェントを介して転送されます。『Oracle Fusion Middleware Oracle WebLogic Server ストア アンド フォワードのコンフィグレーションと管理』を参照してください。
ソース送り先と対象送り先の両方が WebLogic Server 9.0 以降のメッセージング ブリッジ インスタンスである場合は、メッセージング ブリッジの PreserveMsgProperty
を有効にすると、順序単位名を維持してプロデューサの順序単位を設定できます。『Oracle Fusion Middleware Oracle WebLogic Server Tuxedo Connector 管理ガイド』を参照してください。
この節では、順序単位を使用する際に考慮すべきその他の一般情報を示します。
ブラウザの列挙値には、現在のキュー メッセージがブラウザによって受信されるべき順序で格納される。ここでいう「現在」とは、配信可能になっているメッセージを指します。通常は、順序単位内の最初のメッセージが配信可能になっています。同じ順序単位内の後続のメッセージは配信可能にはなっていません。
順序単位機能の組み合わせによっては、競合する順序単位メッセージ ストリームが不足することがある。これには、順序単位名が異なる処理中メッセージの数よりコンシューマの数が多くなったために、リソースが十分に利用されなくなった場合も含まれます。システムのパフォーマンスを最適化し、リソースが十分に利用されない状態を防ぐには、最大の負荷でアプリケーションをテストする必要があります。
このリリースの WebLogic Server メッセージ順序単位では、順序単位非対応の JMS プロバイダ (WebLogic 9.0 より前のリリースや WebLogic 以外の JMS プロバイダ) に接続されているクライアントはサポートされない。