Oracle® Fusion Middleware Oracle WebLogic Server JMSのプログラミング 12cリリース(12.1.1) B65902-02 |
|
前 |
次 |
この章では、作業単位メッセージ・グループを使用して、WebLogic JMSの使用時にメッセージのグループを提供する方法について説明します。
多くのアプリケーションでは、メッセージ順序単位(UOO)によって提供されるグループよりも限定的なグループの定義が必要になります。作業単位メッセージ・グループでは、アプリケーションがJMSメッセージを送信すると、その一部がグループとして識別され、JMSコンシューマがそれらのメッセージをグループとして処理できるようになります。たとえば、JMSプロデューサでメッセージが1つの単位として処理されるように、1つのクライアントに中断なしで配信する必要のあるメッセージの集合を指定できます。また、すでに完了した単位がある場合に、別の単位の完了を待つためにクライアントがブロックされることはありません。
注意: 同一のJMSメッセージで、メッセージ順序単位と作業単位の両方の機能を使用すると、プログラム・エラーが発生します。 |
以下の節では、メッセージ作業単位を使用して、WebLogic JMSの使用時にメッセージの厳格なグループ化を提供する方法について説明します。
ここでは、UOWメッセージ・グループの基本的な概念について説明します。
表11-1に、UOWの定義に使用する用語をまとめます。
表11-1 作業単位に関する用語
用語 | 定義 |
---|---|
作業単位(UOW) |
1つの単位として処理する必要のあるJMSメッセージのセット。 |
UOW構成メッセージ |
UOWの一部となるメッセージ。WebLogic JMSでメッセージをUOWの一部として識別するには、そのメッセージに「UOWメッセージ・プロパティを設定するプロデューサの記述方法」で説明するJMSプロパティが設定されている必要があります。 |
UOWプロデューサ |
作業を複数に分割する必要のあるプロデューサ(たとえば、UOWのクリエータ)。「メッセージ作業単位のケース・スタディ」で説明するように、複数のプロデューサを同時に使用して、UOWメッセージの複数の構成メッセージを処理できます。 現実に、あるUOWプロデューサでUOWを途中まで処理し、別のプロデューサでUOWメッセージを完成させることが可能です。その際も、構成メッセージの整合性は同様の厳格さで維持されます(たとえば、重複の検出など)。 |
中間宛先 |
構成メッセージを1つの単位としてではなく別々に処理するコンシューマのための宛先。UOWにおいて、中間宛先を特別に構成する必要はありません。 中間宛先に届いた構成メッセージは、他の構成メッセージが届くのを待つことなく処理できます。また、中間宛先が分散宛先である場合でも、特別なルーティングを発生させる必要はありません。「中間宛先のUOWコンシューマおよびプロデューサの記述方法」を参照してください。 |
最終宛先 |
UOW全体を処理するコンシューマのための宛先。宛先を最終宛先として指定するには、スタンドアロンの宛先、分散宛先、またはJMSテンプレートで作業単位メッセージ処理ポリシー」パラメータを使用します。最終宛先の構成を参照してください。 |
使用可能/表示可能なメッセージ |
消費の準備が整い、先行するメッセージの受信を保留しているメッセージを指すJMS用語。たとえば、JMSメッセージは生成時間になるまで使用可能になりません。また、トランザクションの一部として送信されたJMSメッセージは、トランザクションがコミットされるまでは表示可能になりません。 |
UOWメッセージには、以下のルールが適用されます。
ルール1 :すべてのメッセージを処理しなければならない
UOW内のメッセージは、すべてのメッセージが最終宛先で使用できる状態になるまでは使用できません。
ルール2 :メッセージの並べ替え
メッセージは、最終宛先に届いた順序に関係なく、UOWプロデューサに指定されている順序に並べ替えられます。
ルール3 :間隔なしで配信される
メッセージのグループは、間隔なしでユーザーに配信されます。つまり、グループ内のすべてのメッセージは、別のグループからのメッセージやグループに属していないメッセージより前にユーザーに配信されます。
ルール4 :単一のコンシューマで消費する
グループ内のすべてのメッセージは、同じコンシューマに配信されます。
この節では、複数の企業の様々な商品をオンラインで注文する場合を例に、メッセージ作業単位の単純なケース・スタディを行います。
Megazonオンライン・ショップには、JMSを使用して顧客からの様々な商品の注文を処理するための処理設計が実装されています。一部の商品の注文は、Megazonの提携企業にルーティングする必要があります。たとえば、本の注文はMegazonで直接処理できますが、特定の電化製品や家庭用品の注文の一部は提携企業に再ルーティングしなければなりません。MegazonはUOWを使用するように構成されているため、注文された商品をUOWメッセージとして中間宛先にルーティングして処理してから、注文を構成するすべてのUOWメッセージを最終宛先に集めて最終的な請求処理が行われます。
MegazonのJMS処理システムは、以下から構成されます。
1つのUOWプロデューサ。注文を履行するための構成メッセージに必要なUOWプロパティを設定し、適切な中間宛先や最終宛先に送信します。
本以外の注文に使用する複数の中間宛先。中間宛先では、UOW最終宛先にルーティングされる前のUOW構成メッセージが、コンシューマ・クライアントやプロデューサ・クライアントによって処理されます。
1つのUOW最終宛先。最終宛先では、構成メッセージを集めて最終的な処理を行います。
ここでは、顧客JillがMegazonのアカウントにログインして、休暇に向けた買い物をするとします。彼女は、本、フラッシュ・ドライブ、MP3プレーヤ、ラーヴァ・ランプを注文して精算を済ませます。
注文を受け付けたJMSプロデューサ・クライアントは、Jillの注文に関わるメッセージが1単位として処理されるようにするため、注文メッセージにUOWプロパティを設定して、それらがこの注文単位の一部であることを示します。設定されたUOWメッセージ・プロパティは、UOWメッセージが最終宛先にルーティングされる前に、中間宛先(Gadget Planet、Widget World、およびDesperate Housewares)をリスニングするすべてのコンシューマ・クライアントやプロデューサ・クライアントによってコピーされます。また、Megazonのシステム管理者は、最終宛先の「作業単位(UOW)メッセージ処理ポリシー」パラメータを「単一のメッセージ配信」に設定しておく必要があります。「作業単位メッセージ・グループの作成方法」を参照してください。
次の図とそれに対応する各アクションは、メッセージ作業単位を使用した場合にJillの注文がどのように処理されるかを示します。
Jillが、ショッピング・カートから注文ボタンをクリックします。
この注文が、同一の一意のUOW名を使用する3つのメッセージに分割されます。
SEQ#1は、中間キューGadget Planetにルーティングされ、コンシューマによってフラッシュ・ドライブの注文が処理されます。処理されたSEQ#1はプロデューサに渡され、中間キューWidget Worldにルーティングされます。Widget WorldのコンシューマによってMP3プレーヤの注文が処理された後、最終的な請求処理のためMegazon最終キューにルーティングされます。
SEQ#2は、中間キューDesperate Housewaresにルーティングされ、そこでコンシューマがラーヴァ・ランプの注文を処理してからSEQ#1をプロデューサに渡し、プロデューサがそれを最終的な請求処理のためにMegazon最終処理キューにルーティングします。
SEQ#3は、Megazon最終キューに直接ルーティングされ、本の注文処理と最終的な請求処理が行われます。
Megazon最終キューでは、集められた3つのUOWメッセージからObjectMessage
リストが作成されます。このリストは、Megazonの請求コンシューマ・クライアントに配信されます。
Jillが、すべての注文が処理されたことを示す請求書を受け取ります。
以下の節では、メッセージ作業単位を作成する方法について説明します。
UOWでは、プロデューサによって複数に分割された作業を別々に処理することができます。これらの複数のメッセージは、最終的には1つにまとめられます。構成メッセージは、1つのメッセージの一部として配信するか複数のメッセージとして配信するかに関係なく、個別のメッセージと同様の仮想的な単一メッセージとして捉えるほうが簡単に理解できます。
WebLogic JMSでメッセージをUOWの一部として識別するには、そのメッセージに表11-1に示すJMSプロパティを設定する必要があります。これらのプロパティは、プロデューサ・クライアントによって設定されます。
表11-2 作業単位プロパティ
UnitOfWork
プロパティを設定しない場合、SequenceNumber
およびEnd
は無視されます。
次に示すクライアントのサンプル・コードでは、表11-1に定義されているUOWプロパティを設定しています。
例11-1 サンプルUOWプロデューサのメッセージ・プロパティ
for (int i=1; i<=100; i++) { sendMsg.setStringProperty("JMS_BEA_UnitOfWork","joule"); sendMsg.setIntProperty("JMS_BEA_UnitOfWorkSequenceNumber",i); if (i == 100) { System.out.println("set the end of message flag for message # " + i); sendMsg.setBooleanProperty("JMS_BEA_IsUnitOfWorkEnd",true); } qSender.send(sendMsg, DeliveryMode.PERSISTENT,7,0); }
JMSメッセージを最終宛先に送信する際に、プロデューサに対して以下の例外がスローされる可能性があります。UOW例外がスローされた場合、そのUOWメッセージは配信されません。
最後のJMS例外を除くすべての例外はJMSException
のサブクラスで、weblogic.jms.extensions
パッケージに含まれています。
BadSequenceNumberException
- この例外は、(a)メッセージにUnitOfWork
が設定されているにもかかわらずSequenceNumber
が設定されていない場合、または(b) SequenceNumber
にゼロ以下の値が設定されている場合にスローされます。
OutOfSequenceRangeException
- この例外は、(a) 送信されたメッセージのシーケンス番号が、単位の最後としてマークされているメッセージのシーケンス番号より大きい場合、または、(b) 送信されたメッセージのシーケンス番号が、同じ単位内のすでに届いているメッセージのシーケンス番号より小さいにもかかわらず、そのメッセージが最後のメッセージとしてマークされている場合に、スローされます。
DuplicateSequenceNumberException
- この例外は、プロデューサが同じUOW内で以前に送信したメッセージと同じシーケンス番号で別のメッセージを送信した場合にスローされます。
JMSException
- メッセージにUnitOfOrder
プロパティ・セットとUnitOfWork
プロパティ・セットの両方が設定されている場合には、JMS例外がスローされます。
注意: ベスト・プラクティスとしては、新しいUOWのすべての構成メッセージが、UOWプロデューサによって単一のトランザクションで送信されるようにプログラミングすることを心がけてください。このようにすると、すべての作業が完了しているか、すべての作業が完了していないか、どちらかの状態にしかなりません。たとえば、UOWプロデューサが例外を受け取ったり、UOWの途中でクラッシュしたりした場合、現在のUOWを取り消したければトランザクション全体をロールバックできます。その結果、障害後に各メッセージをどのように処理するかをアプリケーションで判断する必要がなくなります。 |
中間宛先は、コンポーネント・メッセージを1つの単位としてではなく別々に処理するコンシューマのための宛先です。中間宛先のプロデューサやコンシューマの記述には、JMS ForwardHelper
例外APIを使用します。これは、着信メッセージから送信メッセージにコピーする必要のあるメッセージ・プロパティの数が多いためです。たとえば、UOWの動作を制御するメッセージ・プロパティなどをコピーする必要があります。
次に示す中間コンシューマのサンプル・コードでは、表11-2に定義されているUOWプロパティをコピーしています。
例11-2 UOW中間宛先のサンプル・クライアント・コード
msg = qReceiver1.receive(); try { text = msg.getText(); TextMessage forwardmsg = qsess.createTextMessage(); forwardmsg.setText(text); forwardmsg.setStringProperty("JMS_BEA_UnitOfWork", msg.getStringProperty("JMS_BEA_UnitOfWork")); forwardmsg.setIntProperty("JMS_BEA_UnitOfWorkSequenceNumber", msg.getIntProperty("JMS_BEA_UnitOfWorkSequenceNumber")); if (tm.getBooleanProperty("JMS_BEA_IsUnitOfWorkEnd")) forwardmsg.setBooleanProperty("JMS_BEA_IsUnitOfWorkEnd", msg.getBooleanProperty("JMS_BEA_IsUnitOfWorkEnd")); qsend.send(forwardmsg); }
このサンプルでは、3つのUOWプロパティを着信メッセージから送信メッセージにコピーしています。
宛先を最終宛先として指定するには、スタンドアロンの宛先、分散宛先、またはJMSテンプレートで作業単位メッセージ処理ポリシー」パラメータを使用します。他にも、未完了の作業の最終宛先での有効期限を設定するためのパラメータがあります。
これらの高度なオプションは管理コンソールから設定できます。すべてのタイプの宛先(DestinationBean
APIでも可能)、またはJMSテンプレート(TemplateBean
APIでも可能)の全般構成のページを使用して設定します。
表11-3 作業単位の構成オプション
フィールド名/MBean名 | 説明 |
---|---|
「作業単位(UOW)メッセージ処理ポリシー」 UnitOfWorkHandlingPolicy |
宛先の作業単位(UOW)機能を有効にするかどうかを指定します。
|
「不完全なUOWメッセージの有効期間」 IncompleteWorkExpirationTime |
未完了のUOW内の配信不能なメッセージが期限切れになるまでの最長時間(ミリ秒)を指定します。このオプションが設定されたメッセージは、配信不能メッセージ用に定義されている有効期限ポリシーに従います。メッセージの有効期限は、最初のUOWメッセージが届いた時点から開始されます。 このフィールドは、作業単位処理ポリシーが 注意: 最終宛先での有効期限を構成しないと、いずれかの構成メッセージが(A)送信またはコミットされない場合、(B)期限切れになった場合、または(C)手動で削除された場合に、UOWメッセージが最終宛先で無期限に待機する可能性があります。 |
管理コンソールで、スタンドアロンの宛先、分散宛先、またはJMSテンプレートに作業単位パラメータを構成する手順については、Oracle WebLogic Server管理コンソール・オンライン・ヘルプにある次の項を参照してください。
これらのパラメータの詳細は、Oracle WebLogic Server MBeanリファレンスのDestinationBean
とTemplateBean
を参照してください。
「順序単位のルーティング」フィールドでは、共通分散宛先のUOWメッセージのルーティングを、パス・サービスで行うかハッシュ・ベースで行うかを指定します。UOOの場合と同様、UOW最終宛先が分散宛先である場合も、UOW内のすべてのメッセージを同じ分散宛先メンバーにルーティングする必要があります。UOOのルーティング・メカニズムの詳細は、「分散宛先で順序単位を使用する」を参照してください。
ただし、基本的なUOOルーティングとUOWルーティングはまったく同じではありません。厳密には、単一のUOO内のすべてのメッセージを同じメンバーにルーティングする必要はなく、そのUOOに未消費のメッセージがない場合は、新しく届いたメッセージをどのメンバーにルーティングしても構いません。一方UOWでは、UOW全体が同じ物理的宛先に届くまでは、消費とは無関係にメッセージのルーティングが保証されている必要があります。
次に示すUOWコンシューマのサンプル・コードでは、最終宛先をリスニングするコンシューマによって、送信されたすべての構成メッセージが最終的なUOWメッセージに含まれていることを検証する方法を示します。
例11-3 UOW最終宛先のサンプル・クライアント・コード
{ msg = qReceiver1.receive(); if (msg != null) { count++; System.out.println"Message received: " + msg); //Check that this one message contains all the messages sent. ArrayList msgList = (ArrayList)(((ObjectMessage)msg).getObject()); numMsgs = msgList.size(); System.out.println("no. of messages in the msg = " + numMsgs); } } while (msg != null);
以下の節では、より高度で複雑な状況での作業単位によるメッセージ処理方法について説明します。
UOWでは、複数のメッセージが最終的に1つにまとめられます。この点は、メッセージが1つのメッセージとして配信されるかどうかには関係ありません。たとえば、各メッセージにそれぞれ別の有効期限が設定されている場合でも、いずれかのメッセージの期限が切れるとすべてのメッセージが配信されません。したがって、ベスト・プラクティスとしては、UOWを構成するメッセージができる限り均一になるようにメッセージ・プロデューサを構成する必要があります。
構成メッセージは、1つのメッセージの一部として配信するか複数のメッセージとして配信するかに関係なく、個別のメッセージと同様の仮想的な単一メッセージとして捉えるほうが簡単に理解できます。たとえば、メッセージは連続的に認識する必要があるため、UOWによるメッセージの並べ替え機能は、仮想メッセージの正しい配置を決定する機能と考えることができます。メッセージの選択の場合も同じです。コンシューマは、グループ全体を認識するか、まったく認識しないかのどちらかでなければなりません。WebLogic JMSでは、「コンシューマA」にすべてのメッセージを配信することを決定する前に、「コンシューマA」が仮想メッセージを認識していなければなりません。
仮想メッセージの一部のフィールドは、構成メッセージとは無関係に設定される必要があります。たとえば、仮想メッセージは、配信回数の値を構成メッセージから取得することはできません。以下に、このようなシステム生成のプロパティ値を示します。
タイムスタンプ
配信回数(再配信)
宛先
上記以外のメッセージ・プロパティは、構成メッセージから派生します。ただし、派生の方法は、それぞれのプロパティの特性に応じて異なります。派生方法の1つは、構成メッセージのプロパティの値を直接取得する方法です。この方法では、プロパティ値が異なる構成メッセージの処理が簡略化され、UOW内の最後のメッセージを、値を派生させるためのメッセージとして使用します。たとえば、仮想メッセージの優先度は、最後のメッセージとしてマークされている(JMS_BEA_IsUnitOfWorkEnd
プロパティがtrueに設定されている)メッセージの優先度と同じになります。
以下に、UOW内の最後のメッセージのプロパティ値から派生する仮想メッセージ・プロパティを示します。
メッセージID
相関ID
優先度
ユーザー・プロパティ
ユーザーID
もう1つの派生方法は、構成メッセージの不均一性に対処するため、すべての構成メッセージを同じ値に変換する方法です。たとえば、先に触れたように、有効期限が統一されていないのは合理的ではありません。以下に、この方法で処理されるメッセージ・プロパティ値を示します。
配信モード
有効期限
「UOWメッセージの最終分散宛先へのルーティング」で説明したように、「順序単位のルーティング」フィールドはUOWメッセージのルーティング・メカニズムを指定するために使用します。分散宛先でのUOWにはもう1つ要件があり、すべての宛先メンバーのUOW処理ポリシーに同じ値を設定する必要があります。これ以外の構成は無効です。
ベスト・プラクティスとしては、UOW中間宛先としてトピック(特に分散トピック)を使用しないことです。このような構成では、構成メッセージが重複するおそれがあります。
WebLogicストア・アンド・フォワード・サービスでもUOWがサポートされています。ただし、ストア・アンド・フォワード(SAF)インポート済み宛先を最終宛先にすることはできません。しかし、SAFは、UOOメッセージの場合と同じようにUOWメッセージのルーティング・ルールに従います。「WebLogicストア・アンド・フォワードで順序単位を使用する」を参照してください。
この節では、UOWを使用する際に考慮すべきその他の一般情報を示します。
WebLogic Server 9.0以前のリリースを使用して作成されたJMSクライアントでは、UOWの一部として処理されるメッセージを作成できません。
最終宛先のUOWメッセージはオブジェクト・メッセージであるため、JMS C JNIクライアントでは処理できません。しかし、それをUOWプロデューサとして使用したり、中間宛先で使用したりすることは可能です。
UOWは、サイズの大きなファイル転送には適していません。お使いのメッセージング環境において、できれば最大メッセージ・サイズが最低値に設定されており、サイズの大きなデータ(大きいファイルなど)は単一のプロデューサから単一つのコンシューマにストリーミング転送されるようになっているのが理想です。UOWでは、個別のメッセージをコンシューマに渡す前にサーバー上で1つの大きなメッセージにまとめるため、このようなストリーミング転送は処理しません。