|
以下の節では、作業単位メッセージ グループを使用して、WebLogic JMS の使用時にメッセージのグループを提供する方法について説明します。
多くのアプリケーションでは、メッセージ順序単位 (UOO) によって提供されるグループよりも限定的なグループの定義が必要になります。そのため、リリース 9.2 では作業単位 (UOW) メッセージ グループが導入されました。作業単位メッセージ グループでは、アプリケーションが JMS メッセージを送信すると、その一部がグループとして識別され、JMS コンシューマがそれらのメッセージをグループとして処理できるようになります。たとえば、JMS プロデューサでメッセージが 1 つの単位として処理されるように、1 つのクライアントに中断なしで配信する必要のあるメッセージの集合を指定できます。また、すでに完了した単位がある場合に、別の単位の完了を待つためにクライアントがブロックされることはありません。
以下の節では、メッセージ作業単位を使用して、WebLogic JMS の使用時にメッセージの厳格なグループ化を提供する方法について説明します。
ここでは、UOW メッセージ グループの基本的な概念について説明します。
表 11-1 に、UOW の定義に使用する用語をまとめます。
|
|
この節では、複数の企業のさまざまな商品をオンラインで注文する場合を例に、メッセージ作業単位の単純なケース スタディを行います。
Megazon オンライン ショップには、JMS を使用して顧客からのさまざまな商品の注文を処理するための処理設計が実装されています。一部の商品の注文は、Megazon の提携企業にルーティングする必要があります。たとえば、本の注文は Megazon で直接処理できますが、特定の電化製品や家庭用品の注文の一部は提携企業に再ルーティングしなければなりません。Megazon は UOW を使用するようにコンフィグレーションされているため、注文された商品を UOW メッセージとして中間送り先にルーティングして処理してから、注文を構成するすべての UOW メッセージを最終送り先に集めて最終的な請求処理が行われます。
Megazon の JMS 処理システムは、以下から構成されます。
ここでは、顧客 Jill が Megazon のアカウントにログインして、休暇に向けた買い物をするとします。彼女は、本、フラッシュ ドライブ、MP3 プレーヤー、ラーヴァ ランプを注文して精算を済ませます。
注文を受け付けた JMS プロデューサ クライアントは、Jill の注文に関わるメッセージが 1 単位として処理されるようにするため、注文メッセージに UOW プロパティを設定して、それらがこの注文単位の一部であることを示します。設定された UOW メッセージ プロパティは、UOW メッセージが最終送り先にルーティングされる前に、中間送り先 (Gadget Planet、Widget World、および Desperate Housewares) をリスンするすべてのコンシューマ クライアントやプロデューサ クライアントによってコピーされます。また、Megazon のシステム管理者は、最終送り先の [作業単位 (UOW) メッセージ処理ポリシー] パラメータを [単一のメッセージ配信] に設定しておく必要があります。「作業単位メッセージ グループの作成方法」を参照してください。
次の図とそれに対応する各アクションは、メッセージ作業単位を使用した場合に Jill の注文がどのように処理されるかを示します。
ObjectMessage
リストが作成されます。このリストは、Megazon の請求コンシューマ クライアントに配信されます。
以下の節では、メッセージ作業単位を作成する方法について説明します。
UOW では、プロデューサによって複数に分割された作業を別々に処理することができます。これらの複数のメッセージは、最終的には 1 つにまとめられます。構成メッセージは、1 つのメッセージの一部として配信するか複数のメッセージとして配信するかに関係なく、個別のメッセージと同様の仮想的な単一メッセージとして捉えるほうが簡単に理解できます。
WebLogic JMS でメッセージを UOW の一部として識別するには、そのメッセージに表 11-2 に示す JMS プロパティを設定する必要があります。これらのプロパティは、プロデューサ クライアントによって設定されます。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/UUID.html を参照。
|
|
UnitOfWork
プロパティを設定しない場合、SequenceNumber
および End
は無視されます。
次に示すクライアントのサンプル コードでは、表 11-2 に定義されている 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 プロパティをコピーしています。
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 でも可能) の全般コンフィグレーションのページを使用して設定します。
Administration Console で、スタンドアロンの送り先、分散送り先、または JMS テンプレートに作業単位パラメータをコンフィグレーションする手順については、Administration Console オンライン ヘルプの以下の節を参照してください。
これらのパラメータの詳細については、『WebLogic Server MBean リファレンス』の「DestinationBean
」と「TemplateBean
」を参照してください。
[順序単位のルーティング] フィールドでは、共通分散送り先の UOW メッセージのルーティングを、パス サービスで行うかハッシュ ベースで行うかを指定します。UOO の場合と同様、UOW 最終送り先が分散送り先である場合も、UOW 内のすべてのメッセージを同じ分散送り先メンバーにルーティングする必要があります。UOO のルーティング メカニズムの詳細については、『WebLogic JMS プログラマーズ ガイド』の「分散送り先で順序単位を使用する」を参照してください。
ただし、基本的な UOO ルーティングと UOW ルーティングはまったく同じではありません。厳密には、単一の UOO 内のすべてのメッセージを同じメンバーにルーティングする必要はなく、その UOO に未消費のメッセージがない場合は、新しく届いたメッセージをどのメンバーにルーティングしても構いません。一方 UOW では、UOW 全体が同じ物理的送り先に届くまでは、消費とは無関係にメッセージのルーティングが保証されている必要があります。
次に示す UOW コンシューマのサンプル コードでは、最終送り先をリスンするコンシューマによって、送信されたすべての構成メッセージが最終的な 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 内の最後のメッセージのプロパティ値から派生する仮想メッセージ プロパティを示します。
もう 1 つの派生方法は、構成メッセージの不均一性に対処するため、すべての構成メッセージを同じ値に変換する方法です。たとえば、先に触れたように、有効期限が統一されていないのは合理的ではありません。以下に、この方法で処理されるメッセージ プロパティ値を示します。
ReplyTo
プロパティの値は、仮想メッセージには反映されません。このプロパティは、メッセージの選択や並べ替えには使用されず、アプリケーションでしか使用しないため無視されます。
「UOW メッセージの最終分散送り先へのルーティング」で説明したように、[順序単位のルーティング] フィールドは UOW メッセージのルーティング メカニズムを指定するために使用します。分散送り先での UOW にはもう 1 つ要件があり、すべての送り先メンバーの UOW 処理ポリシーに同じ値を設定する必要があります。これ以外のコンフィグレーションは無効です。
ベスト プラクティスとしては、UOW 中間送り先としてトピック (特に分散トピック) を使用しないことです。このようなコンフィグレーションでは、構成メッセージが重複するおそれがあります。
WebLogic ストア アンド フォワード サービスでも UOW がサポートされています。ただし、ストア アンド フォワード (SAF) インポート済み送り先を最終送り先にすることはできません。しかし、SAF は、UOO メッセージの場合と同じように UOW メッセージのルーティング ルールに従います。詳細については、『WebLogic JMS プログラマーズ ガイド』の「WebLogic ストア アンド フォワードで順序単位を使用する」を参照してください。
この節では、UOW を使用する際に考慮すべきその他の一般情報を示します。