Oracle® Fusion Middleware Oracle WebLogic Server JMS プログラマーズ ガイド 11g リリース 1 (10.3.1) B55536-01 |
|
![]() 戻る |
![]() 次へ |
以下の節では、作業単位メッセージ グループを使用して、WebLogic JMS の使用時にメッセージのグループを提供する方法について説明します。
多くのアプリケーションでは、メッセージ順序単位 (UOO) によって提供されるグループよりも限定的なグループの定義が必要になります。そのため、WebLogic JMS では作業単位 (UOW) メッセージ グループが導入されました。作業単位メッセージ グループでは、アプリケーションが 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 テンプレートで [作業単位 (UOW) メッセージ処理ポリシー] パラメータを使用する。「最終送り先のコンフィグレーション」を参照。 |
使用可能/表示可能なメッセージ |
消費の準備が整い、先行するメッセージの受信を保留しているメッセージを指す 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#2 はプロデューサに渡され、最終的な請求処理のため Megazon 最終キューにルーティングされます。
SEQ#3 は、Megazon 最終キューに直接ルーティングされ、本の注文処理と最終的な請求処理が行われます。
Megazon 最終キューでは、集められた 3 つの UOW メッセージから ObjectMessage
リストが作成されます。このリストは、Megazon の請求コンシューマ クライアントに配信されます。
Jill が、すべての注文が処理されたことを示す請求書を受け取ります。
以下の節では、メッセージ作業単位を作成する方法について説明します。
UOW では、プロデューサによって複数に分割された作業を別々に処理することができます。これらの複数のメッセージは、最終的には 1 つにまとめられます。構成メッセージは、1 つのメッセージの一部として配信するか複数のメッセージとして配信するかに関係なく、個別のメッセージと同様の仮想的な単一メッセージとして捉えるほうが簡単に理解できます。
WebLogic JMS でメッセージを UOW の一部として識別するには、そのメッセージに表 11-1 に示す JMS プロパティを設定する必要があります。これらのプロパティは、プロデューサ クライアントによって設定されます。
表 11-2 作業単位プロパティ
タイプ | 説明 |
---|---|
JMS_BEA_UnitOfWork |
JMS の標準のプロパティ設定メカニズムによって設定される文字列プロパティ。次に例を示す。 message.setStringProperty("JMS_BEA_UnitOfWork", "MyUnitOfWorkName") 名前の衝突を防ぐため、UOW ID を再利用しないようにする必要がある。たとえば、メッセージが消失した場合または再転送された場合に、別の UOW の一部として認識される可能性がある。そのため、Oracle では Java UUID (Universally Unique Identifier) を使用することを推奨している。 |
JMS_BEA_UnitOfWorkSequenceNumber |
JMS の標準のプロパティ設定メカニズムによって設定される整数プロパティ。次に例を示す。 message.setIntProperty("JMS_BEA_UnitOfWorkSequenceNumber", 5) 整数値として有効なのは 1 以上の値。 |
JMS_BEA_IsUnitOfWorkEnd |
JMS の標準のプロパティ設定メカニズムによって設定されるブール プロパティ。次に例を示す。 message.setBooleanProperty("JMS_BEA_IsUnitOfWorkEnd", true) このプロパティを true に設定すると、このメッセージが作業単位内の最後のメッセージになる。このプロパティを false に設定すると、このメッセージは作業単位内の最後のメッセージにはならない。設定しない場合のデフォルト値は false。 |
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) 送信されたメッセージのシーケンス番号が、同じ UOW 内で最後のメッセージとしてマークされているメッセージのシーケンス番号より大きい場合、または (b) 送信されたメッセージのシーケンス番号が、同じ UOW 内のすでに届いているメッセージのシーケンス番号より小さいにもかかわらず、そのメッセージが最後のメッセージとしてマークされている場合に送出されます。
DuplicateSequenceNumberException
- この例外は、プロデューサが同じ UOW 内で以前に送信したメッセージと同じシーケンス番号で別のメッセージを送信した場合に送出されます。
JMSException
- メッセージに UnitOfOrder
プロパティ セットと UnitOfWork
プロパティ セットの両方が設定されている場合には、JMS 例外が送出されます。
注意 : ベスト プラクティスとしては、新しい UOW のすべての構成メッセージが、UOW プロデューサによって単一のトランザクションで送信されるようにプログラミングすることを心がけてください。このようにすると、すべての作業が完了しているか、すべての作業が完了していないか、どちらかの状態にしかなりません。たとえば、UOW プロデューサが例外を受け取ったり、UOW の途中でクラッシュしたりした場合、現在の UOW をキャンセルしたければトランザクション全体をロールバックできます。その結果、障害後に各メッセージをどのように処理するかをアプリケーションで判断する必要がなくなります。 |
「中間送り先」は、構成メッセージを 1 つの単位としてではなく別々に処理するコンシューマのための送り先です。中間送り先のプロデューサやコンシューマの記述には、JMS ForwardHelper
例外 API を使用します。この 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 テンプレートで [作業単位 (UOW) メッセージ処理ポリシー] パラメータを使用します。他にも、未完了の作業の最終送り先での有効期限を設定するためのパラメータがあります。
これらの高度なオプションは Administration Console から設定できます。すべてのタイプの送り先 (DestinationBean
API でも可能)、または JMS テンプレート (TemplateBean
API でも可能) の全般コンフィグレーションのページを使用して設定します。
表 11-3 作業単位のコンフィグレーション オプション
フィールド名/MBean 名 | 説明 |
---|---|
[作業単位 (UOW) メッセージ処理ポリシー] UnitOfWorkHandlingPolicy |
送り先の作業単位 (UOW) 機能を有効にするかどうかを指定する。
|
[不完全な UOW メッセージの有効期間] IncompleteWorkExpirationTime |
未完了の UOW 内の配信不能なメッセージが期限切れになるまでの最長時間 (ミリ秒) を指定する。このオプションが設定されたメッセージは、配信不能メッセージ用に定義されている有効期限ポリシーに従う。メッセージの有効期限は、最初の UOW メッセージが届いた時点から開始される。 このフィールドは、作業単位処理ポリシーが [単一のメッセージ配信 注意 : 最終送り先での有効期限をコンフィグレーションしないと、いずれかの構成メッセージが (A) 送信またはコミットされない場合、(B) 期限切れになった場合、または (C) 手動で削除された場合に、UOW メッセージが最終送り先で無期限に待機する可能性がある。 |
Administration Console で、スタンドアロンの送り先、分散送り先、または JMS テンプレートに作業単位パラメータをコンフィグレーションする手順については、Oracle Fusion Middleware Oracle WebLogic Server の Administration Console オンライン ヘルプにある以下の節を参照してください。
これらのパラメータの詳細については、『Oracle Fusion Middleware Oracle WebLogic Server MBean Reference』の「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); // この 1 つのメッセージに、送信されたすべてのメッセージが含まれていることを確認する。 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 8.1 以前のリリースを使用して作成された JMS クライアントでは、UOW の一部として処理されるメッセージを作成できない。
最終送り先の UOW メッセージはオブジェクト メッセージであるため、JMS C JNI クライアントでは処理できない。しかし、JMS C JNI クライアントを UOW プロデューサとして使用したり、中間送り先で使用したりすることは可能です。
UOW は、サイズの大きなファイル転送には適していない。お使いのメッセージング環境において、できれば最大メッセージ サイズが最低値に設定されており、サイズの大きなデータ (大きいファイルなど) は単一のプロデューサから単一つのコンシューマにストリーミング転送されるようになっているのが理想です。UOW では、個別のメッセージをコンシューマに渡す前にサーバ上で 1 つの大きなメッセージにまとめるため、このようなストリーミング転送は処理しません。