BEA ホーム | 製品 | dev2dev | support | askBEA
 ドキュメントのダウンロード   サイト マップ   Glossary 
検索

WebLogic JMS プログラマーズ ガイド

 Previous Next Contents Index PDF で侮ヲ  

WebLogic JMS アプリケーションの開発

以下の節では、WebLogic Server JMS アプリケーションを開発する方法について説明します。

注意: この節で説明する JMS クラスの詳細については、Sun Microsystems の Java Web サイト (http://java.sun.com/products/jms/docs.html) にある JMS Javadoc を参照してください。

 


アプリケーション開発フロー

WebLogic JMS アプリケーションを開発するには、次の図に示す手順を行う必要があります。

図4-1 WebLogic JMS アプリケーション開発フロー - 必要な手順


 

上の図に示したアプリケーション開発手順の他にも、設計開発時に以下の手順を任意に行うことができます。

以降の節では、すべてのアプリケーション開発手順について説明します (最後の手順を除く)。

 


必要なパッケージのインポート

次の表に、WebLogic JMS アプリケーションで一般に使用されるパッケージを示します。

表4-1 WebLogic JMS パッケージ

パッケージ名

説明

javax.jms

Sun Microsystems の JMS API。このパッケージは常に WebLogic JMS アプリケーションで使用される。

java.util

日付や時刻機能などのユーティリティ API。

java.io

システム入力および出力 API。

javax.naming

weblogic.jndi

サーバおよび送り先ルックアップに必要な JNDI パッケージ。

javax.transaction.UserTransaction

JTA ユーザ トランザクション サポートに必要な JTA API。

weblogic.jms.ServerSessionPoolFactory

JMS 仕様で定義されているオプションのアプリケーション サーバ機能、サーバ セッション プールを使用するための WebLogic JMS パブリック API。

weblogic.jms.extensions

追加のクラスとメソッドを提供する WebLogic 固有の JMS パブリック API (WebLogic JMS の拡張機能を参照)。

プログラムの最初に、以下のパッケージ import 文を挿入します。

import javax.jms.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.transaction.*;

サーバ セッション プール アプリケーションを実装する場合は、次のクラスをインポート リストに追加します。

import weblogic.jms.ServerSessionPoolFactory;

上の表に示した WebLogic JMS 拡張クラスを使用する場合は、次の文もインポート リストに追加します。

import weblogic.jms.extensions.*;

 


JMS アプリケーションの設定

メッセージを送受信するには、あらかじめ JMS アプリケーションを設定しておく必要があります。次の図に、JMS アプリケーションの設定に必要な手順を示します。

図4-2 JMS アプリケーションの設定


 

以下の節では、この設定手順について説明します。また、ポイント ツー ポイント (PTP) およびパブリッシュ/サブスクライブ (Pub/Sub) アプリケーションの詳しい例も示します。これらの例は、WL_HOME¥samples¥server¥src¥examples¥jms ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms パッケージからの抜粋です。

設定手順に進む前に、WebLogic Server のコンフィグレーションを担当するシステム管理者が必要な JMS 機能 (接続ファクトリ、JMS サーバ、送り先など) をコンフィグレーションしたことを確認してください。詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

これらの節で説明する JMS クラスおよびメソッドの詳細については、WebLogic JMS のクラス、または javax.jmsweblogic.jms.ServerSessionPoolFactoryweblogic.jms.extensions の Javadoc を参照してください。

トランザクション アプリケーションと JTA ユーザ トランザクションの設定については、WebLogic JMS によるトランザクションの使い方を参照してください。

手順 1 :JNDI で接続ファクトリをルックアップする

接続ファクトリをルックアップするには、あらかじめ接続ファクトリをコンフィグレーション情報の一部として定義しておく必要があります。WebLogic JMS には、コンフィグレーションの一部として組み込まれているデフォルト接続ファクトリが 1 つ用意されています。WebLogic JMS システム管理者は、コンフィグレーション時に接続ファクトリを追加または更新できます。接続ファクトリのコンフィグレーションと使用可能なデフォルトについては、『管理者ガイド』の「JMS の管理」を参照してください。

接続ファクトリを定義したら、その接続ファクトリをルックアップするために、まず NamingManager.InitialContext() メソッドを使用して JNDI コンテキスト (context) を定義します。サーブレット アプリケーション以外のアプリケーションの場合は、初期コンテキストの作成に使用する環境を渡す必要があります。詳細については、NamingManager.InitialContext() Javadoc を参照してください。

コンテキストを定義したら、JNDI で接続ファクトリをルックアップするために、以下のコマンド (PTP または Pub/Sub メッセージング用) のいずれかを実行します。

QueueConnectionFactory queueConnectionFactory = 
(QueueConnectionFactory) context.lookup(CF_name);
TopicConnectionFactory topicConnectionFactory = 
(TopicConnectionFactory) context.lookup(CF_name);

CF_name 引数には、コンフィグレーション時に定義した接続ファクトリ名を指定します。

ConnectionFactory クラスの詳細については、ConnectionFactory、または javax.jms.ConnectionFactory Javadoc を参照してください。

手順 2 :接続ファクトリを使用して接続を作成する

キューまたはトピックにアクセスするための接続を作成するには、以降の節で説明する ConnectionFactory メソッドを使用します。

Connection クラスの詳細については、Connection、または javax.jms.Connection Javadoc を参照してください。

キュー接続の作成

QueueConnectionFactory は、キュー接続を作成するための、以下の 2 つのメソッドを提供します。

public QueueConnection createQueueConnection(
) throws JMSException
public QueueConnection createQueueConnection(
String userName,
String password
) throws JMSException

最初のメソッドは QueueConnection を作成し、2 番目のメソッドは指定されたユーザ ID を使用して QueueConnection を作成します。どちらのケースでも、接続は停止モードで作成されます。メッセージを受け付けるには、手順 7 :接続を開始するで説明するとおりに接続を開始しなければなりません。

QueueConnectionFactory クラス メソッドの詳細については、javax.jms.QueueConnectionFactory Javadoc を参照してください。QueueConnection クラスの詳細については、javax.jms.QueueConnection Javadoc を参照してください。

トピック接続の作成

TopicConnectionFactory は、トピック接続を作成するための、以下の 2 つのメソッドを提供します。

public TopicConnection createTopicConnection(
) throws JMSException
public TopicConnection createTopicConnection(
String userName,
String password
) throws JMSException

最初のメソッドは TopicConnection を作成し、2 番目のメソッドは指定されたユーザ ID を使用して TopicConnection を作成します。どちらのケースでも、接続は停止モードで作成されます。メッセージを受け付けるには、手順 7 :接続を開始するで説明するとおりに接続を開始しなければなりません。

TopicConnectionFactory クラス メソッドの詳細については、javax.jms.TopicConnectionFactory Javadoc を参照してください。TopicConnection クラスの詳細については、javax.jms.TopicConnection Javadoc を参照してください。

手順 3 :接続を使用してセッションを作成する

キューまたはトピックにアクセスするために 1 つまたは複数のセッションを作成するには、以降の節で説明する Connection メソッドを使用します。

注意: セッションおよびそのメッセージのプロデューサとコンシューマには、一度に 1 つのスレッドしかアクセスできません。それらに複数のスレッドが同時にアクセスした場合、それらの動作は定義されません。

Session クラスの詳細については、Session、または javax.jms.Session Javadoc を参照してください。

キュー セッションの作成

QueueConnection クラスは、キュー セッション作成用の次のメソッドを定義します。

public QueueSession createQueueSession(
boolean transacted,
int acknowledgeMode
) throws JMSException

このメソッドでは、セッションをトランザクション処理するか (true)、またはトランザクション処理しないか (false) を示す boolean 引数と、表2-5で説明した非トランザクション セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション セッションの場合、acknowledgeMode 属性は無視されます。この場合、メッセージは commit() メソッドでトランザクションがコミットされたときに確認応答されます。

QueueConnection クラス メソッドの詳細については、javax.jms.QueueConnection Javadoc を参照してください。QueueSession クラスの詳細については、javax.jms.QueueSession Javadoc を参照してください。

トピック セッションの作成

TopicConnection クラスは、トピック セッション作成用の次のメソッドを定義します。

public TopicSession createTopicSession(
boolean transacted,
int acknowledgeMode
) throws JMSException

このメソッドでは、セッションをトランザクション処理するか (true)、またはトランザクション処理しないか (false) を示す boolean 引数と、非トランザクション セッションで使用する確認応答モードで説明した非トランザクション セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション セッションの場合、acknowledgeMode 属性は無視されます。この場合、メッセージは commit() メソッドでトランザクションがコミットされたときに確認応答されます。

TopicConnection クラス メソッドの詳細については、javax.jms.TopicConnection Javadoc を参照してください。TopicSession クラスの詳細については、javax.jms.TopicSession Javadoc を参照してください。

手順 4 :送り先 (キューまたはトピック) をルックアップする

送り先をルックアップするには、あらかじめ WebLogic JMS システム管理者によって送り先がコンフィグレーションされている必要があります。詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

送り先のコンフィグレーションが済んでいれば、JNDI コンテキスト (context) を定義し (手順 1 :JNDI で接続ファクトリをルックアップするで実行済み)、以下のコマンド (PTP または Pub/Sub メッセージング用) のいずれかを実行することによって、送り先をルックアップできます。

Queue queue = (Queue) context.lookup(Dest_name);
Topic topic = (Topic) context.lookup(Dest_name);

Dest_name 引数には、コンフィグレーション時に定義された送り先名を指定します。

JNDI ネームスペースを使用しない場合は、以下の QueueSession または TopicSession メソッドを使用してキューまたはトピックをそれぞれ参照できます。

public Queue createQueue(
String queueName
) throws JMSException
public Topic createTopic(
String topicName
) throws JMSException

queueNametopicName 文字列の構文は、JMS_Server_Name/Destination_Name (たとえば、myjmsserver/mydestination) です。この構文を使用するソース コードを参照するには、送り先の動的作成findqueue() の例を参照してください。

注意: createQueue() メソッドと createTopic() メソッドでは送り先が動的には作成されず、既に存在する送り先への参照が作成されるだけです。送り先の動的作成については、送り先の動的作成を参照してください。

これらのメソッドの詳細については、それぞれ javax.jms.QueueSession Javadoc と javax.jms.TopicSession Javadoc を参照してください。

送り先を定義したら、以下の Queue メソッドまたは Topic メソッドを使用してキューまたはトピックにそれぞれアクセスできます。

public String getQueueName(
) throws JMSException
public String getTopicName(
) throws JMSException

キュー名とトピック名が印刷可能なフォーマットで返されるようにするには、toString() メソッドを使用します。

Destination クラスの詳細については、Destination、または javax.jms.Destination Javadoc を参照してください。

送り先ルックアップ時のサーバ アフィニティ

createTopic() および createQueue() メソッドでは、「JMS_Server_Name./Destination_Name」構文を使用して、送り先をルックアップする場合のサーバ アフィニティを示すこともできます。送り先が接続ファクトリとして同じ JVM にローカルにデプロイされている場合、接続ファクトリからはローカルの送り先と一致する名前のみが返されます。名前がローカル JVM にない場合は、同じ名前が別の JVM にデプロイされていても例外が送出されます。

アプリケーションでこの規約を利用すると、createTopic() メソッドおよび createQueue() メソッドを使用する場合にサーバ名をハードコード化せずに済むので、コードを変更しなくても別の JVM でコードを再利用できます。

手順 5 :セッションと送り先を使用してメッセージ プロデューサとメッセージ コンシューマを作成する

メッセージ プロデューサとメッセージ コンシューマを作成するには、以降の節で説明する Session メソッドに送り先の参照を渡します。

注意: 各コンシューマはメッセージの独自のローカル コピーを受信します。受信が済んだら、ヘッダ フィールド値を変更することはできますが、メッセージ プロパティとメッセージ本文は読み込み専用です。(この時点でメッセージ プロパティまたは本文を変更しようとすると、MessageNotWriteableException が発生します)。メッセージ本文を変更するには、対応するメッセージ タイプの clearbody() メソッドを実行して、既存の内容を消去し、書き込みパーミッションを有効にします。

MessageProducer クラスと MessageConsumer クラスの詳細については、MessageProducer と MessageConsumer、または javax.jms.MessageProducer Javadoc とja vax.jms.MessageConsumer Javadoc をそれぞれ参照してください。

QueueSender と QueueReceiver の作成

QueueSession オブジェクトは、キュー センダとキュー レシーバを作成するための、以下のメソッドを定義します。

public QueueSender createSender(
Queue queue
) throws JMSException
public QueueReceiver createReceiver(
Queue queue
) throws JMSException
public QueueReceiver createReceiver(
Queue queue,
String messageSelector
) throws JMSException

作成するキュー センダまたはキュー レシーバに関連付けるキュー オブジェクトを指定しなければなりません。また、メッセージをフィルタ処理するためのメッセージ セレクタを指定できます。メッセージ セレクタの詳細については、メッセージのフィルタ処理を参照してください。

createSender() メソッドに null 値を渡すと、匿名プロデューサが作成されます。この場合、メッセージの送信で説明するように、メッセージの送信時にキュー名を指定しなければなりません。

キュー センダまたはキュー レシーバの作成が済んだら、以下の QueueSender メソッドまたは QueueReceiver メソッドを使用して、そのキュー センダまたはレシーバに関連付けられているキュー名にアクセスできます。

public Queue getQueue(
) throws JMSException

QueueSession クラス メソッドの詳細については、javax.jms.QueueSession Javadoc を参照してください。QueueSender クラスと QueueReceiver クラスの詳細については、javax.jms.QueueSender Javadoc および javax.jms.QueueReceiver Javadoc をそれぞれ参照してください。

TopicPublisher と TopicSubscriber の作成

TopicSession オブジェクトは、トピック パブリッシャとトピック サブスクライバを作成するための、以下のメソッドを定義します。

public TopicPublisher createPublisher(
Topic topic
) throws JMSException
public TopicSubscriber createSubscriber(
Topic topic
) throws JMSException
public TopicSubscriber createSubscriber(
Topic topic,
String messageSelector,
boolean noLocal
) throws JMSException

注意: この節で説明するメソッドでは、非恒久サブスクライバが作成されます。非恒久トピック サブスクライバは、アクティブな間だけメッセージを受信します。恒久サブスクリプションを作成して、すべてのメッセージが恒久サブスクライバに届けられるまでメッセージを保持できるようにするためのメソッドについては、恒久サブスクリプションの設定を参照してください。この場合、恒久サブスクライバはサブスクライバがサブスクライブした後にパブリッシュされたメッセージのみを受信します。

作成するパブリッシャまたはサブスクライバに関連付けるトピック オブジェクトを指定しなければなりません。また、メッセージをフィルタ処理するためのメッセージ セレクタと noLocal フラグ (この節で後述) を指定できます。メッセージ セレクタの詳細については、メッセージのフィルタ処理を参照してください。

createPublisher() メソッドに null 値を渡すと、匿名プロデューサが作成されます。この場合、メッセージの送信で説明するように、メッセージの送信時にトピック名を指定しなければなりません。

アプリケーションは、JMS 接続を使用して同じトピックに対してパブリッシュとサブスクライブの両方を行う場合があります。トピック メッセージはすべてのサブスクライバに届けられるので、アプリケーションは自身がパブリッシュしたことを示すメッセージを受信する可能性があります。この動作を防ぐために、JMS アプリケーションは noLocal フラグを true に設定できます。

トピック パブリッシャまたはトピック サブスクライバの作成が済んだら、以下の TopicPublisher メソッドまたは TopicSubscriber メソッドを使用して、そのトピック パブリッシャまたはサブスクライバに関連付けられているトピック名にアクセスできます。

Topic getTopic(
) throws JMSException

また、次の TopicSubscriber メソッドを使用すると、トピック サブスクライバに関連付けられる noLocal 変数の設定値にアクセスできます。

boolean getNoLocal(
) throws JMSException

TopicSession クラス メソッドの詳細については、javax.jms.TopicSession Javadoc を参照してください。TopicPublisher クラスと TopicSubscriber クラスの詳細については、javax.jms.TopicPublisher Javadoc および javax.jms.TopicSubscriber Javadoc をそれぞれ参照してください。

手順 6a :メッセージ オブジェクトを作成する
(メッセージ プロデューサ)

注意: この手順は、メッセージ プロデューサだけに適用されます。

メッセージ オブジェクトを作成するには、以下の Session クラス メソッドまたは WLSession クラス メソッドのいずれかを使用します。

Session クラスと WLSession クラス メソッドの詳細については、javax.jms.Session Javadoc とwebl ogic.jms.extensions.WLSession Javadoc をそれぞれ参照してください。Message クラスとそのメソッドの詳細については、Message、または javax.jms.Message Javadoc を参照してください。

手順 6b :非同期メッセージ リスナを登録する (オプション) (メッセージ コンシューマ)

注意: この手順は、メッセージ コンシューマだけに適用されます。

メッセージを非同期的に受信するには、次の手順で非同期メッセージ リスナを登録する必要があります。

  1. onMessage() メソッドが組み込まれた javax.jms.MessageListener インタフェースを実装します。

    注意: onMessage() メソッドのインタフェースの例については、例 :PTP アプリケーションの設定を参照してください。
    onMessage() メソッド呼び出し内で close() メソッドを発行する場合、システム管理者は接続ファクトリをコンフィグレーションするときに [メッセージの短縮を許可] チェックボックスをチェックしなければなりません。JMS のコンフィグレーションの詳細については、『 管理者ガイド』の「JMS の管理」を参照してください。

  2. 次の MessageConsumer メソッドを使用してメッセージ リスナを設定し、リスナ情報を引数として渡します。
    public void setMessageListener(
    MessageListener listener
    ) throws JMSException

  3. オプションで、セッション例外リスナの定義で説明するように、例外を取得するためのセッションの例外リスナを実装します。

メッセージ リスナの設定を解除するには、null 値を指定して MessageListener() メソッドを呼び出します。

メッセージ リスナを定義したら、次の MessageConsumer メソッドを呼び出してそのリスナにアクセスできます。

public MessageListener getMessageListener(
) throws JMSException

注意: WebLogic JMS は、同じセッションの複数の onMessage() 呼び出しが同時に実行されないことを保証します。

メッセージ コンシューマが管理者またはサーバのダウンによってクローズされた場合、ConsumerClosedException がセッション例外リスナに送信されます (定義されている場合)。このように、必要な場合は新しいメッセージ コンシューマを作成できます。セッション例外リスナの定義については、セッション例外リスナの定義を参照してください。

MessageConsumer クラスのメソッドは、QueueReceiver クラスおよび TopicSubscriber クラスによって継承されます。MessageConsumer クラス メソッドの詳細については、MessageProducer と MessageConsumer、または javax.jms.MessageConsumer Javadoc を参照してください。

手順 7 :接続を開始する

接続を開始するには、Connection クラスの start() メソッドを使用します。

接続の開始、停止、およびクローズの詳細については、接続の開始、停止、クローズ、またはja vax.jms.Connection Javadoc を参照してください。

例 :PTP アプリケーションの設定

次の例は、WL_HOME¥samples¥server¥src¥examples¥jms¥queue ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.queue.QueueSend の例からの抜粋です。init() メソッドは、JMS アプリケーションの QueueSession をどのように設定して開始するかを示すものです。次に、その init() メソッドを示し、併せて各設定手順も述べます。

必要な変数 (JNDI コンテキストなど)、JMS 接続ファクトリ、およびキュー静的変数を定義します。

public final static String JNDI_FACTORY=
"weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY=
"weblogic.examples.jms.QueueConnectionFactory";
public final static String
QUEUE="weblogic.examples.jms.exampleQueue";

private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;

JNDI 初期コンテキストを次のとおり設定します。

InitialContext ic = getInitialContext(args[0]);
.
.
.
private static InitialContext getInitialContext(
String url
) throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}

注意: サーブレットの JNDI 初期コンテキストを設定する場合は、以下のメソッドを使用します。

Context ctx = new InitialContext();

JMS キューにメッセージを送信するのに必要なすべてのオブジェクトを作成します。ctx オブジェクトは、main() メソッドによって渡された JNDI 初期コンテキストです。

public void init(
Context ctx,
String queueName
) throws NamingException, JMSException
{

手順 1

JNDI で接続ファクトリをルックアップします。

  qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);

手順 2

接続ファクトリを使用して接続を作成します。

  qcon = qconFactory.createQueueConnection();

手順 3

接続を使用してセッションを作成します。次のコードでは、セッションが非トランザクションとして定義され、メッセージに対する確認応答が自動的に行われるものと指定されます。トランザクション セッションと確認応答モードの詳細については、Session を参照してください。

  qsession = qcon.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);

手順 4

JNDI で送り先 (キュー) をルックアップします。

  queue = (Queue) ctx.lookup(queueName);

手順 5

セッションと送り先 (キュー) を使用してメッセージ プロデューサ (キュー センダ) への参照を作成します。

  qsender = qsession.createSender(queue);

手順 6

メッセージ オブジェクトを作成します。

  msg = qsession.createTextMessage();

手順 7

接続を開始します。

  qcon.start();
}

examples.jms.queue.QueueReceive の例の init() メソッドは、前記の QueueSend init() メソッドとほぼ同じですが、例外が 1 つあります。手順 5 と手順 6 は、それぞれ以下のコードに置き換えられます。

qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);

最初の行では、createSender() メソッドを呼び出してキュー センダへの参照を作成する代わりに、アプリケーションは createReceiver() メソッドを呼び出してキュー レシーバを作成します。

2 番目の行では、メッセージ コンシューマは非同期メッセージ リスナを登録します。

メッセージがキュー セッションに届くと、そのメッセージは examples.jms.QueueReceive.onMessage() メソッドに渡されます。次の QueueReceive の例からの引用コードは、onMessage() インタフェースを示したものです。

public void onMessage(Message msg)
{
try {
String msgText;
if (msg instanceof TextMessage) {
msgText = ((TextMessage)msg).getText();
} else { // TextMessage ではない場合...
msgText = msg.toString();
}
	System.out.println("Message Received:"+ msgText );
	if (msgText.equalsIgnoreCase("quit")) {
synchronized(this) {
	   	quit = true;
this.notifyAll(); // メイン スレッドに終了するよう通知する
}
}
} catch (JMSException jmse) {
jmse.printStackTrace();
}
}

onMessage() メソッドは、キュー レシーバを通して受信したメッセージを処理します。このメソッドは、メッセージが TextMessage であるかどうかを検証し、そうである場合は、そのメッセージのテキストを出力します。onMessage() が別のタイプのメッセージを受信した場合、そのメッセージの toString() メソッドを使用してメッセージの内容を表示します。

注意: 受信したメッセージのタイプが、メッセージ ハンドラ メソッドが予期したタイプであるかどうかを検証するようにしてください。

この例で使用した JMS クラスの詳細については、WebLogic JMS のクラス、または avax.jms Javadoc を参照してください。

例 :Pub/Sub アプリケーションの設定

次の例は、WL_HOME¥samples¥server¥src¥examples¥jms¥topic ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.topic.TopicSend の例からの抜粋です。init() メソッドは、JMS アプリケーションのトピック セッションをどのように設定して開始するかを示すものです。次に、その init() メソッドを示し、併せて各設定手順も述べます。

必要な変数 (JNDI コンテキストなど)、JMS 接続ファクトリ、およびトピック静的変数を定義します。

public final static String JNDI_FACTORY=
"weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY=
"weblogic.examples.jms.TopicConnectionFactory";
public final static String
TOPIC="weblogic.examples.jms.exampleTopic";
protected TopicConnectionFactory tconFactory;
protected TopicConnection tcon;
protected TopicSession tsession;
protected TopicPublisher tpublisher;
protected Topic topic;
protected TextMessage msg;

JNDI 初期コンテキストを次のとおり設定します。

InitialContext ic = getInitialContext(args[0]);
.
.
.
private static InitialContext getInitialContext(
String url
) throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}

注意: サーブレットの JNDI 初期コンテキストを設定する場合は、以下のメソッドを使用します。

Context ctx = new InitialContext();

JMS キューにメッセージを送信するのに必要なすべてのオブジェクトを作成します。ctx オブジェクトは、main() メソッドによって渡された JNDI 初期コンテキストです。

public void init(
Context ctx,
String topicName
) throws NamingException, JMSException
{

手順 1

JNDI を使用して接続ファクトリをルックアップします。

    tconFactory = 
(TopicConnectionFactory) ctx.lookup(JMS_FACTORY);

手順 2

接続ファクトリを使用して接続を作成します。

    tcon = tconFactory.createTopicConnection();

手順 3

接続を使用してセッションを作成します。次のコードでは、セッションが非トランザクションとして定義され、メッセージに対する確認応答が自動的に行われるものと指定されます。セッション トランザクションと確認応答モードの設定については、Session を参照してください。

    tsession = tcon.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);

手順 4

JNDI を使用して送り先 (トピック) をルックアップします。

    topic = (Topic) ctx.lookup(topicName);

手順 5

セッションと送り先 (トピック) を使用してメッセージ プロデューサ (トピック パブリッシャ) への参照を作成します。

    tpublisher = tsession.createPublisher(topic);

手順 6

メッセージ オブジェクトを作成します。

    msg = tsession.createTextMessage();

手順 7

接続を開始します。

    tcon.start();
}

examples.jms.topic.TopicReceive の例の init() メソッドは、前記の TopicSend init() メソッドとほぼ同じですが、例外が 1 つあります。手順 5 と手順 6 は、それぞれ以下のコードに置き換えられます。

tsubscriber = tsession.createSubscriber(topic);
tsubscriber.setMessageListener(this);

最初の行では、createPublisher() メソッドを呼び出してトピック パブリッシャへの参照を作成する代わりに、アプリケーションは createSubscriber() メソッドを呼び出してトピック サブスクライバを作成します。

2 番目の行では、メッセージ コンシューマは非同期メッセージ リスナを登録します。

メッセージがトピック セッションに届くと、そのメッセージは examples.jms.TopicSubscribe.onMessage() メソッドに渡されます。TopicReceiveonMessage() インタフェースは、QueueReceive onMessage() インタフェース (例 :PTP アプリケーションの設定を参照) と同じです。

この例で使用した JMS クラスの詳細については、WebLogic JMS のクラス、またはja vax.jms Javadoc を参照してください。

 


メッセージの送信

JMS アプリケーションの設定で説明したとおり JMS アプリケーションを設定したら、メッセージを送信することができます。メッセージを送信するには、次の手順を実行する必要があります。

  1. メッセージ オブジェクトを作成する。

  2. メッセージを定義する。

  3. メッセージを送り先に送信する。

メッセージを送信するための JMS クラスとメッセージ タイプの詳細については、javax.jms.Message Javadoc を参照してください。メッセージの受信については、メッセージの受信を参照してください。

手順 1 :メッセージ オブジェクトを作成する

この手順は、手順 6a :メッセージ オブジェクトを作成する (メッセージ プロデューサ)で説明したように、クライアント設定手順の一部として既に実行されています。

手順 2 :メッセージを定義する

この手順は、手順 6a :メッセージ オブジェクトを作成する (メッセージ プロデューサ)で説明したように、アプリケーションの設定時に実行されている場合もあります。この手順が実行済みであるかどうかは、メッセージ オブジェクトを作成するために呼び出されたメソッドによって決まります。たとえば、TextMessage タイプと ObjectMessage タイプの場合は、メッセージ オブジェクトを作成するときにオプションでメッセージを定義することができます。

既に値が指定されており、それを変更したくない場合は、そのまま手順 3 に進みます。

値が指定されていないか、または既存の値を変更する場合は、適切な set メソッドを使用して値を定義できます。たとえば、TextMessage のテキストを定義するメソッドは次のとおりです。

public void setText(
String string
) throws JMSException

注意: メッセージは null として定義することができます。

それ以後は、次のメソッドを使用してメッセージを消去できます。

public void clearBody(
) throws JMSException

メッセージを定義するためのメソッドの詳細については、javax.jms.Session Javadoc を参照してください。

手順 3 :メッセージを送り先に送信する

メッセージを送り先に送信するには、メッセージ プロデューサ-キュー センダ (PTP) またはトピック パブリッシャ (Pub/Sub) -と以下の節で説明するメソッドを使用します。Destination オブジェクトと MessageProducer オブジェクトは、JMS アプリケーションの設定で説明したとおり、アプリケーションの設定時に作成されています。

注意: 同じトピックに対して複数のトピック サブスクライバが定義されている場合、各サブスクライバはメッセージの独自のローカル コピーを受信します。受信が済んだら、ヘッダ フィールド値を変更することはできますが、メッセージ プロパティとメッセージ本文は読み込み専用です。メッセージ本文を変更するには、対応するメッセージ タイプの clearbody() メソッドを実行して、既存の内容を消去し、書き込みパーミッションを有効にします。

MessageProducer クラスの詳細については、MessageProducer と MessageConsumer、またはja vax.jms.MessageProducer Javadoc を参照してください。

キュー センダを使用してメッセージを送信する

メッセージを送信するには、以下の QueueSender メソッドを使用します。

public void send(
Message message
) throws JMSException
public void send(
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException
public void send(
Queue queue,
Message message
) throws JMSException
public void send(
Queue queue,
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException

まず、メッセージを定義する必要があります。また、キュー名 (匿名メッセージ プロデューサ用)、配信モード (DeliveryMode.PERSISTENT または DeliveryMode.NON_PERSISTENT)、優先度 (0-9)、および存続時間 (ミリ秒単位) も指定する必要があります。指定しない場合、配信モード、優先度、および存続時間の各属性は以下のいずれかに設定されます。

注意: WebLogic JMS も、独自の TimeToDeliver 属性 (生成時間) を提供します (メッセージ プロデューサ コンフィグレーション属性の動的コンフィグレーションを参照)。

配信モードを PERSISTENT として定義した場合、『管理者ガイド』の「JMS の管理」で説明してあるように、送り先のバッキング ストアをコンフィグレーションする必要があります。

注意: バッキング ストアがコンフィグレーションされていない場合、配信モードは NON_PERSISTENT に変更され、メッセージは永続ストレージに書き込まれません。

キュー センダが匿名プロデューサである場合 (つまり、キューが作成されたときにその名前が null に設定された場合)、キュー名を指定して (最後の 2 つのメソッドのいずれかを使用する) メッセージの配信先を指示する必要があります。匿名プロデューサの定義の詳細については、QueueSender と QueueReceiver の作成を参照してください。

たとえば、次のコードは、永続的メッセージを優先度 4、存続時間 1 時間で送信します。

QueueSender.send(message, DeliveryMode.PERSISTENT, 4, 3600000);

QueueSender クラス メソッドの詳細については、javax.jms.QueueSender Javadoc を参照してください。

TopicPublisher を使用してメッセージを送信する

メッセージを送信するには、以下の TopicPublisher メソッドを使用します。

public void publish(
Message message
) throws JMSException
public void publish(
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException
public void publish(
Topic topic,
Message message
) throws JMSException
public void publish(
Topic topic,
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException

メッセージを指定する必要があります。また、トピック名、配信モード (DeliveryMode.PERSISTENT または DeliveryMode.NON_PERSISTENT)、優先度 (0-9)、および存続時間 (ミリ秒単位) も指定する必要があります。指定しない場合、配信モード、優先度、および存続時間の各属性は以下のいずれかに設定されます。

注意: WebLogic JMS も、独自の TimeToDeliver 属性 (生成時間) を提供します (メッセージ プロデューサ コンフィグレーション属性の動的コンフィグレーションを参照)。

配信モードを PERSISTENT として定義した場合、『管理者ガイド』の「JMS の管理」で説明してあるようにバッキング ストアをコンフィグレーションする必要があります。

注意: バッキング ストアがコンフィグレーションされていない場合、配信モードは NON_PERSISTENT に変更され、メッセージは保存されません。

トピック パブリッシャが匿名プロデューサである場合 (つまり、トピックが作成されたときにその名前が null に設定された場合)、トピック名を指定して (最後の 2 つのメソッドのいずれかを使用する) メッセージの配信先を指示する必要があります。匿名プロデューサの定義の詳細については、TopicPublisher と TopicSubscriber の作成を参照してください。

たとえば、次のコードは、永続的メッセージを優先度 4、存続時間 1 時間で送信します。

TopicPublisher.publish(message, DeliveryMode.PERSISTENT,
4,3600000);

TopicPublisher クラス メソッドの詳細については、javax.jms.TopicPublisher Javadoc を参照してください。

メッセージ プロデューサ コンフィグレーション属性の動的コンフィグレーション

前節で説明したように、メッセージを送信するときには、配信モード、優先度、存続時間、および配信時間をオプションで指定できます。指定しない場合、配信モード、優先度、存続時間、および配信時間の各属性は、『管理者ガイド』の「JMS の管理」で説明しているように、プロデューサに対して定義されている接続ファクトリまたは送り先オーバーライドのコンフィグレーション属性に設定されます。

代わりに、メッセージ プロデューサ set メソッドを使用して配信モード、優先度、および存続時間を動的に設定することによって、コンフィグレーション済みの属性値をオーバーライドすることもできます。

次の表に、メッセージ プロデューサの set メソッドと get メソッドを、動的コンフィグレーション可能な属性ごとに示します。

注意: 配信モード、優先度、存続時間、配信時間の各属性値は、[配信モードのオーバライド]、[優先順位オーバライド]、[生存時間のオーバライド]、および [配信時間のオーバライド] 送り先コンフィグレーション属性を使用して、送り先によってオーバーライドできます。詳細については、Administration Console オンライン ヘルプを参照してください。

表4-2 メッセージ プロデューサの set メソッドおよび get メソッド

属性

set メソッド

get メソッド

配信モード

public void setDeliveryMode(
int deliveryMode
) throws JMSException

public int getDeliveryMode(
) throws JMSException

優先度

public void setPriority(
int defaultPriority
) throws JMSException

public int getPriority(
) throws JMSException

存続時間

public void setTimeToLive(
long timeToLive
) throws JMSException

public long getTimeToLive(
) throws JMSException

配信時間

public void setTimeToDeliver(
long timeToDeliver
) throws JMSException

public long getTimeToDeliver(
) throws JMSException

注意: JMS では、メッセージ ID とタイムスタンプ情報を無効にするための MessageProducer メソッドを定義することもできます。ただし、これらのメソッドは WebLogic JMS では無視されます。

MessageProducer クラス メソッドの詳細については、javax.jms.MessageProducer Javadoc を参照してください。

例 :PTP アプリケーション内でのメッセージの送信

次の例は、WL_HOME¥samples¥server¥src¥examples¥jms¥queue ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.queue.QueueSend の例からの抜粋です。この例では、TextMessage を作成し、メッセージのテキストを設定してキューに送信するために必要なコードを示してあります。

msg = qsession.createTextMessage();
.
.
.
public void send(
String message
) throws JMSException
{
msg.setText(message);
qsender.send(msg);
}

QueueSender クラスとメソッドの詳細については、javax.jms.QueueSender Javadoc を参照してください。

例 :Pub/sub アプリケーション内でのメッセージの送信

次の例は、WL_HOME¥samples¥server¥src¥examples¥jms¥topic ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.topic.TopicSend の例からの抜粋です。この例では、TextMessage を作成し、メッセージのテキストを設定してトピックに送信するために必要なコードを示してあります。

msg = tsession.createTextMessage();
.
.
.
public void send(
String message
) throws JMSException
{
msg.setText(message);
tpublisher.publish(msg);
}

TopicPublisher クラスとメソッドの詳細については、javax.jms.TopicPublisher Javadoc を参照してください。

 


メッセージの受信

JMS アプリケーションの設定で説明したとおり JMS アプリケーションを設定したら、メッセージを受信することができます。

メッセージを受信するには、以下の節で説明するとおりレシーバ オブジェクトを作成し、メッセージを同期受信するか非同期受信するかを指定する必要があります。

メッセージを受信する順序は、以下の要素によって設定できます。

受信が済んだら、ヘッダ フィールド値を変更することはできますが、メッセージ プロパティとメッセージ本文は読み込み専用です。メッセージ本文を変更するには、対応するメッセージ タイプの clearbody() メソッドを実行して、既存の内容を消去し、書き込みパーミッションを有効にします。

メッセージを受信するための JMS クラスとメッセージ タイプの詳細については、javax.jms.Message Javadoc を参照してください。メッセージの送信については、メッセージの送信を参照してください。

メッセージの非同期受信

この手順については、アプリケーションの設定手順の中で説明されています。詳細については、手順 6b :非同期メッセージ リスナを登録する (オプション) (メッセージ コンシューマ)を参照してください。

注意: 接続ファクトリのコンフィグレーション時に [最大メッセージ数] 属性を設定すると、非同期セッションの間に存在し、メッセージ リスナにまだ渡されていないメッセージの最大数を指定できます。

メッセージの同期受信

メッセージを同期的に受信するには、以下の MessageConsumer メソッドを使用します。

public Message receive(
) throws JMSException
public Message receive(
long timeout
) throws JMSException
public Message receiveNoWait(
) throws JMSException

どのケースでも、アプリケーションは次に生成されるメッセージを受信します。receive() メソッドを引数なしで呼び出した場合、その呼び出しはメッセージが生成されるか、またはアプリケーションが閉じられるまで無期限にブロックされます。代わりに、タイムアウト値を渡してメッセージの待ち時間を指定することもできます。値 0 を指定して receive() メソッドを呼び出した場合、その呼び出しは無期限にブロックされます。receiveNoWait() メソッドは、次のメッセージが存在する場合はそれを受信し、それ以外の場合は null を返します。この場合、呼び出しはブロックされません。

MessageConsumer クラスのメソッドは、QueueReceiver クラスおよび TopicSubscriber クラスによって継承されます。MessageConsumer クラス メソッドの詳細については、javax.jms.MessageConsumer Javadoc を参照してください。

例 :PTP アプリケーション内でのメッセージの同期受信

次の例は、WL_HOME¥samples¥server¥src¥examples¥jms¥queue ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.queue.QueueReceive の例からの抜粋です。メッセージ リスナを設定するのではなく、各メッセージに対して qreceiver.receive() を呼び出します。次に例を示します。

qreceiver = qsession.createReceiver(queue);
qreceiver.receive();

最初の行では、キューに対するキュー レシーバが作成されます。2 番目の行では、receive() メソッドが実行されます。receive()メソッドは、ブロックしてメッセージを待ちます。

例 :Pub/sub アプリケーション内でのメッセージの同期受信

次の例は、WL_HOME¥samples¥server¥src¥examples¥jms¥topic ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.topic.TopicReceive の例からの抜粋です。メッセージ リスナを設定するのではなく、各メッセージに対して tsubscriber.receive() を呼び出します。

次に例を示します。

tsubscriber = tsession.createSubscriber(topic);
Message msg = tsubscriber.receive();
msg.acknowledge();

最初の行では、トピックに対するトピック サブスクライバが作成されます。2 番目の行では、receive() メソッドが実行されます。receive()メソッドは、ブロックしてメッセージを待ちます。

受信メッセージの回復

注意: この節は、表2-5で説明したように、確認応答モードが CLIENT_ACKNOWLEDGE に設定されている非トランザクション セッションだけに適用されます。同期受信される AUTO_ACKNOWLEDGE メッセージは確認応答済みのため、受信されないことがあります。

アプリケーションは、次のメソッドを使用して、JMS にメッセージの再配信 (未確認) を要求できます。

public void recover(
) throws JMSException

recover() メソッドは、次の手順を実行します。

キュー内のメッセージは、必ずしも元の配信順序と同じ順序で、または同じキュー コンシューマに再配信されるとは限りません。

 


受信メッセージの確認応答

注意: この節は、表2-5で説明したように、確認応答モードが CLIENT_ACKNOWLEDGE に設定されている非トランザクション セッションだけに適用されます。

受信したメッセージの確認応答を行うには、次の Message メソッドを使用します。

public void acknowledge(
) throws JMSException

acknowledge() メソッドは、現在のメッセージと、クライアントの最後の確認応答時から受信した過去のすべてのメッセージの確認応答を行います。確認応答が行われないメッセージは、クライアントに再配信できます。

このメソッドは、確認応答モードが CLIENT_ACKNOWLEDGE に設定されている非トランザクション セッションに対してだけ有効です。それ以外の場合、このメソッドは無視されます。

 


オブジェクト リソースの解放

JMS アプリケーションに代わって作成した接続、セッション、メッセージ プロデューサ/コンシューマ、接続コンシューマ、またはキュー ブラウザを使い終えたら、それらを明示的にクローズしてリソースを解放する必要があります。

JMS オブジェクトをクローズするには、close() メソッドを次のとおり入力します。

public void close(
) throws JMSException

オブジェクトをクローズするときには、以下の処理が行われます。

各オブジェクトの close() メソッドの影響については、適切なja vax.jms Javadoc を参照してください。また、接続またはセッションの close() メソッドの詳細については、接続の開始、停止、クローズ、または セッションのクローズをそれぞれ参照してください。

次の例は、WL_HOME¥samples¥server¥src¥examples¥jms¥queue ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.queue.QueueSend の例からの抜粋です。この例を見れば、メッセージ コンシューマ、セッション、および接続オブジェクトをどのようにクローズするかが分かります。

public void close(
) throws JMSException
{
qreceiver.close();
qsession.close();
qcon.close();
}

この QueueSend の例では、main() の最後に close() メソッドが呼び出され、オブジェクトのクローズとリソースの解放が行われます。

 


ロールバックまたは回復したメッセージの管理

以下の節では、ロールバックまたは回復したメッセージを管理する以下の方法について説明します。

メッセージの再配信遅延の設定

一時的または外部的な要因でアプリケーションがメッセージを正しく処理できない場合に、メッセージの再配信を遅延させることができます。これによって、アプリケーションは、現時点では処理できない「有害な」メッセージを一時的に受信できないようにすることができます。メッセージがロールバックまたは回復される場合、再配信遅延は、メッセージが止められてから再配信が試行されるまでの間隔です。

JMS でメッセージをすぐに再配信すると、エラーの原因が解決されず、アプリケーションはメッセージを処理できないままの場合があります。ただし、アプリケーションが再配信遅延用にコンフィグレーションされている場合、メッセージがロールバックまたは回復されると、メッセージは再配信の遅延が過ぎるまで止められます。遅延の期間を過ぎた時点でエラーが解決されていれば、メッセージを再配信できるようになります。

セッションによって消費された結果、ロールバックまたは回復したすべてのメッセージは、ロールバックまたは回復時にそのセッションの再配信遅延を受信します。単一のユーザ トランザクションの一部として複数のセッションで消費されたメッセージは、個々のメッセージを消費したセッションの機能として異なる再配信遅延を受信します。意識的か、または失敗の結果、クライアントによる確認応答またはコミットされていないメッセージには、再配信遅延が割り当てられません。

再配信遅延の設定

セッションは、作成時に接続ファクトリから再配信遅延を継承します。接続ファクトリの RedeliveryDelay 属性は、Administration Console でコンフィグレーションします。詳細については、Administration Console オンライン ヘルプの「[JMS 接続ファクトリ]」を参照してください。

セッションを作成するアプリケーションは、javax.jms.Session インタフェースに対する WebLogic 固有の拡張を使用して接続ファクトリ設定をオーバーライドできます。セッション属性は動的なので、いつでも変更できます。セッションの再配信遅延を変更すると、変更後にそのセッションで消費およびロールバック (または回復) されるすべてのメッセージに影響します。

セッションに対して再配信遅延を設定するメソッドは、javax.jms.Session インタフェースの拡張である weblogic.jms.extensions.WLSession インタフェースを介して提供されます。セッションの再配信遅延を定義するには、以下のメソッドを使用します。

public void setRedeliveryDelay(
long redeliveryDelay
) throws JMSException;
public long getRedeliveryDelay(
) throws JMSException;

WLSession クラスの詳細については、weblogic.jms.extensions.WLSession Javadoc を参照してください。

送り先での再配信遅延のオーバーライド

再配信遅延がセッションで設定されているかどうかに関係なく、メッセージがロールバックまたは回復される送り先で再配信遅延の設定をオーバーライドできます。メッセージの再配信に割り当てられた再配信遅延のオーバーライドは、メッセージがロールバックまたは回復されるときに有効になります。

送り先の RedeliveryDelayOverride 属性は、Administration Console でコンフィグレーションします。詳細については、Administration Console オンライン ヘルプの「[JMS 送り先]」を参照してください。

メッセージの再配信制限の設定

WebLogic JMS によるアプリケーションへのメッセージ再配信の試行回数に対して制限を設けることができます。WebLogic JMS が送り先へのメッセージ再配信を指定した回数だけ試みて失敗すると、メッセージの送り先に関連付けられたエラー送り先にメッセージをリダイレクトできます。エラー送り先がコンフィグレーションされていない場合、メッセージは自動的に削除されます。

メッセージの再配信制限のコンフィグレーション

送り先によるコンシューマへのメッセージ再配信の試行が指定した再配信制限に達すると、送り先はメッセージを配信不能にします。RedeliveryLimit 属性は、送り先で設定され、Administration Console でコンフィグレーションできます。詳細については、Administration Console オンライン ヘルプの「[JMS 送り先]」を参照してください。

配信されなかったメッセージに対するエラー送り先のコンフィグレーション

配信されなかったメッセージのエラー送り先をコンフィグレーションすると、メッセージが配信不能になったときに、指定したエラー送り先にリダイレクトされます。エラー送り先は、キューでもトピックでもかまいませんが、定義した送り先と同じ JMS サーバでコンフィグレーションする必要があります。エラー送り先がコンフィグレーションされていない場合、配信されなかったメッセージは自動的に削除されます。

送り先の ErrorDestination 属性は、Administration Console でコンフィグレーションします。詳細については、Administration Console オンライン ヘルプの「[JMS 送り先]」を参照してください。

メッセージの再配信試行が既に指定した制限に達しているものの、エラー送り先も最大割り当てに達している場合、メッセージは配信不能になり、削除されます。永続的メッセージは格納され、サーバを再起動すると元の送り先 (エラー送り先ではない) に再表示される一方で、非永続的メッセージは削除されます。いずれの場合も、ログ メッセージが生成されます。ログ ファイルへの書き込みが滞るのを防ぐために、エラーが解決されるまで、ログ メッセージは、エラー送り先ごとに 5 分おきに 1 回だけ生成されます。

 


メッセージ配信時間の設定

アプリケーションへのメッセージ配信を、将来の指定した時間にスケジューリングできます。メッセージ配信は、短期間 (秒や分など) でも長期間 (数時間単位でバッチ処理する場合など) でもかまいません。また、相対配信時間 (ミリ秒単位) で指定することもできます。この時間は、後でメッセージの絶対配信時間に計算されます。その配信時間になって配信されるまでメッセージは表示されないため、将来の特定の時間に作業をスケジューリングできます。

メッセージが送信されるのは 1 回だけで、繰り返し送信されることはありません。メッセージが繰り返し送信されるようにするには、受信したスケジューリング済みのメッセージを元の送信先に戻す必要があります。1 度のみというセマンティクスを保証するため、受信、送信、およびこれらに関連する作業は同じトランザクションのもとで行われます。

プロデューサに対する配信時間の設定

個々のプロデューサに対する配信時間の設定および取得のサポートは、javax.jms.MessageProducer インタフェースの拡張である weblogic.jms.extensions.WLMessageProducer インタフェースを介して提供されます。個々のプロデューサに対して配信時間を定義するには、以下のメソッドを使用します。

public void setTimeToDeliver(
long timeToDeliver
) throws JMSException;
public long getTimeToDeliver(
) throws JMSException;

WLMessageProducer クラスの詳細については、weblogic.jms.extensions.WLMessageProducer Javadoc を参照してください。

メッセージに対する配信時間の設定

注意: ここで説明するメッセージ メソッドは、プロデューサを介して設定する他の JMS メッセージ メソッドと似ています。特に、配信時間の設定は JMS プロバイダ用に予約されます。アプリケーションはメッセージの値を設定できますが、プロデューサは、メッセージが送信またはパブリッシュされたときにその値をオーバーライドします。

DeliveryTime は、メッセージを配信できる最も早い絶対時間を定義する JMS メッセージ ヘッダです。つまり、メッセージはメッセージング システムによって保持され、その時間になるまでどのコンシューマにも配信されません。

DeliveryTime は、JMS ヘッダ フィールドとして送り先でのメッセージのソート、またはメッセージの選択に使用できます。データ型変換の目的で、配信時間は長整数として保存されます。

個々のメッセージに対する配信時間の設定および取得のサポートは、javax.jms.Message インタフェースの拡張である weblogic.jms.extensions.WLMessage インタフェースを介して提供されます。メッセージの配信時間を定義するには、以下のメソッドを使用します。

public void setJMSDeliveryTime(
long deliveryTime
) throws JMSException;
public long getJMSDeliveryTime(
) throws JMSException;

WLMessage クラスの詳細については、weblogic.jms.extensions.WLMessage Javadoc を参照してください。

配信時間のオーバーライド

作成されたプロデューサは、接続の作成に使用する接続ファクトリ (プロデューサもそこに含まれます) から TimeToDeliver 属性 (ミリ秒) を継承します。配信時間がプロデューサで設定されているかどうかに関係なく、メッセージが送信またはパブリッシュされる送り先で配信時間の設定をオーバーライドできます。管理者は、相対形式またはスケジューリング済み文字列形式のいずれかで送り先に対する TimeToDeliverOverride 属性を設定できます。

相対配信時間のオーバーライドの設定

相対 TimeToDeliverOverride は、整数で指定した文字列で、Administration Console でコンフィグレーション可能です。詳細については、Administration Console オンライン ヘルプの「[JMS 送り先]」を参照してください。

スケジューリング済み配信時間のオーバーライドの設定

スケジューリング済み TimeToDeliverOverrideweblogic.jms.extensions.schedule クラスを使用して指定できます。このクラスは、スケジュールを取得し、指定されたメッセージ配信時間を返すメソッドを提供します。cron に似た文字列がスケジュールの定義に使用されます。書式は、次の BNF 構文で定義されます。

schedule := millisecond second minute hour dayOfMonth month
dayOfWeek

second フィールドを指定するための BNF 構文は次のとおりです。

second      := * | secondList
secondList := secondItem [, secondList]
secondItem := secondValue | secondRange
SecondRange := secondValue - secondValue

ミリ秒、分、時、日、月、曜日に対する同様の BNF 文を 2 番目の構文から取得できます。各フィールドの値は、以下の範囲の正の整数で指定します。

milliSecondValue := 0-999
milliSecondValue := 0-999
secondValue := 0-59
minuteValue := 0-59
hourValue := 0-23
dayOfMonthValue := 1-31
monthValue := 1-12
dayOfWeekValue := 1-7

注意: これらの値は、monthValue を除いて、java.util.Calendar クラスで使用するのと同じ範囲です。monthValuejava.util.Calendar の範囲は、1-12 ではなく 0-11 です。

この構文を使用すると、2 つの時間の間のすべての時間を示す値の範囲で各フィールドを表すことができます。たとえば、dayOfWeek フィールドの 2-6 は、月曜から金曜まで (双方の曜日を含む) を示します。また、カンマ区切りのリストで各フィールドを指定することもできます。たとえば、分フィールドの 0,15,30,45 は、1 時間内の 15 分おきの値を示します。さらに、個々の値と値の範囲の組み合わせで各フィールドを定義することもできます。たとえば、時フィールドの 9-17,0 は、午前 9 時と午後 5 時の間と深夜 12 時を示します。

補足のセマンティクスは以下のとおりです。

注意: このクラスの静的メソッドのいずれか 1 つに対するメソッド パラメータとして Calendar が指定されない場合、使用されるカレンダーは、デフォルトの java.util.TimeZone およびデフォルトの java.util.Locale がある java.util.GregorianCalendar です。

表4-3 配信時間のスケジュールの例

説明

0 0 0,30 * * * *

次の最も近い 30 分

* * 0,30 4-5 * * *

午前 4 時から午前 5 時までの 30 分の任意の最初の分

* * * 9-16 * * *

午前 9 時と午後 5 時の間 (9:00.00 A.M. 〜 4:59.59 P.M.)

* * * * 8-14 * 2

その月の第 2 火曜日

* * * 13-16 * * 0

日曜日の午後 1 時と午後 5 時の間

* * * * * 31 *

その月の最後の日

* * * * 15 4 1

次に日曜日になる 4 月 15 日

0 0 0 1 * * 2-6;0 0 0 2 * * 1,7

平日の午前 1 時および週末の午前 2 時

JMS スケジュール インタフェース

weblogic.jms.extensions.schedule クラスには、反復時間式に一致する次のスケジュール時間を返すメソッドがあります。この式は、TimeToDeliverOverride と同じ構文を使用します。ミリ秒で返される時間は、相対でも絶対でもかまいません。

WLSession クラスの詳細については、weblogic.jms.extensions.Schedule Javadoc を参照してください。

次のメソッドを使用すると、指定した時間の後の次のスケジュール時間を定義できます。

public static Calendar nextScheduledTime(
String schedule,
Calendar calendar
) throws ParseException {

次のメソッドを使用すると、現在の時間の後の次のスケジュール時間を定義できます。

public static Calendar nextScheduledTime(
String schedule,
) throws ParseException {

次のメソッドを使用すると、指定した時間の後の次のスケジュール時間を絶対ミリ秒で定義できます。

public static long nextScheduledTimeInMillis(
String schedule,
long timeInMillis
) throws ParseException

次のメソッドを使用すると、指定した時間の後の次のスケジュール時間を相対ミリ秒で定義できます。

public static long nextScheduledTimeInMillisRelative(
String schedule,
long timeInMillis
) throws ParseException {

次のメソッドを使用すると、現在の時間の後の次のスケジュール時間を相対ミリ秒で定義できます。

public static long nextScheduledTimeInMillisRelative(
String schedule
) throws ParseException {

存続時間の値との関係

指定した存続時間の値 (JMSExpiration) が指定した配信時間と同じかそれより少ない場合、メッセージの配信は成功します。ただし、メッセージは通知されずに期限切れになります。

 


接続の管理

以下の節では、接続を管理する方法について説明します。

接続例外リスナの定義

例外リスナは、接続に問題が発生するとアプリケーションに非同期的に通知します。このメカニズムは、通知されない限り接続がメッセージの消費を待ち続ける場合に役立ちます。

注意: 例外リスナの目的は、接続によって送出されたすべての例外をモニタすることではなく、本来なら配信されない例外を配信することです。

接続に対する例外リスナを定義するには、次の Connection メソッドを使用します。

public void setExceptionListener(
ExceptionListener listener
) throws JMSException

接続に対する ExceptionListener オブジェクトを指定しなければなりません。

JMS プロバイダは、接続の問題を発見すると、次の ExceptionListener メソッドを使用して例外リスナ (定義されている場合) に通知します。

public void onException(
JMSException exception
)

JMS プロバイダは、このメソッドを呼び出すときに、問題を説明する例外を指定します。

接続に対する例外リスナにアクセスするには、次の Connection メソッドを使用します。

public ExceptionListener getExceptionListener(
) throws JMSException

接続メタデータへのアクセス

特定の接続に関連付けられているメタデータにアクセスするには、次の Connection メソッドを使用します。

public ConnectionMetaData getMetaData(
) throws JMSException

このメソッドは、JMS メタデータへのアクセスに使用する ConnectionMetaData オブジェクトを返します。次の表に、JMS メタデータのタイプと、それらにアクセスするために使用できる get メソッドを示します。

JMS メタデータ

get メソッド

バージョン

public String getJMSVersion(
) throws JMSException

メジャー バージョン

public int getJMSMajorVersion(
) throws JMSException

マイナー バージョン

public int getJMSMinorVersion(
) throws JMSException

プロバイダ名

public String getJMSProviderName(
) throws JMSException

プロバイダ バージョン

public String getProviderVersion(
) throws JMSException

プロバイダ メジャー バージョン

public int getProviderMajorVersion(
) throws JMSException

プロバイダ マイナー バージョン

public int getProviderMinorVersion(
) throws JMSException

JMSX プロパティ名

public Enumeration getJMSXPropertyNames(
) throws JMSException

ConnectionMetaData クラスの詳細については、javax.jms.ConnectionMetaData Javadoc を参照してください。

接続の開始、停止、クローズ

メッセージの流れを制御するために、以下の start() メソッドと stop() メソッドをそれぞれ使用して、接続を一時的に開始および停止できます。

start() メソッドと stop() メソッドの詳細は以下のとおりです。

public void start(
) throws JMSException
public void stop(
) throws JMSException

新しく作成された接続は停止しています。−接続が開始されるまで、メッセージは受信されません。一般に、他の JMS オブジェクトは、JMS アプリケーションの設定で説明するとおり、接続が開始する前からメッセージを処理するよう設定されます。メッセージは、停止している接続上に作成することはできますが、停止している接続に届けることはできません。

接続が開始されていれば、stop() メソッドを使用して接続を停止できます。このメソッドは、次の手順を実行します。

一般に、JMS プロバイダは接続を作成するときに大量のリソースを割り当てます。接続が使用されなくなったら、その接続をクローズしてリソースを解放する必要があります。接続をクローズするには、次のメソッドを使用します。

public void close(
) throws JMSException

このメソッドは、次の手順を実行して系統的にシャットダウンを行います。

接続をクローズすると、関連付けられているすべてのオブジェクトがクローズされます。受信メッセージの acknowledge() メソッドを除いて、接続で作成または受信されたメッセージ オブジェクトは引き続き使用できます。閉じた接続をクローズしても影響はありません。

注意: クローズされた接続のセッションから受信したメッセージを確認応答しようとすると、IllegalStateException が送出されます。

 


セッションの管理

以下の節では、セッションを管理する方法について説明します。

セッション例外リスナの定義

例外リスナは、セッションに問題が発生すると、クライアントに非同期的に通知します。これは、通知されない限りセッションがメッセージの消費を待ち続ける場合に役立ちます。

注意: 例外リスナの目的は、セッションによって送出されたすべての例外をモニタすることではなく、本来なら通知されない例外を通知することです。

セッションに対する例外リスナを定義するには、次の WLSession メソッドを使用します。

public void setExceptionListener(
ExceptionListener listener
) throws JMSException

セッションに対する ExceptionListener オブジェクトを指定しなければなりません。

JMS プロバイダは、セッションの問題を発見すると、次の ExceptionListener メソッドを使用して例外リスナ (定義されている場合) に通知します。

public void onException(
JMSException exception
)

JMS プロバイダは、このメソッドを呼び出すときに、問題を説明する例外を指定します。

セッションに対する例外リスナにアクセスするには、次の WLSession メソッドを使用します。

public ExceptionListener getExceptionListener(
) throws JMSException

注意: 1 つのセッションに対して 1 つのスレッドしか存在しないので、例外リスナとメッセージ リスナ (非同期メッセージ配信用に使用される) を同時に実行することはできません。そのため、問題が発生したときにメッセージ リスナが実行されている場合、そのメッセージ リスナが実行を完了するまで例外リスナはブロックされます。メッセージ リスナの詳細については、メッセージの非同期受信を参照してください。

セッションのクローズ

接続と同じように、JMS プロバイダはセッションを作成するときに大量のリソースを割り当てます。セッションが使用されなくなったら、そのセッションをクローズしてリソースを解放することをお勧めします。セッションをクローズするには、次の Session メソッドを使用します。

public void close(
) throws JMSException

注意: close() メソッドは、セッション スレッドとは別個のスレッドから呼び出すことができる唯一の Session メソッドです。

このメソッドは、次の手順を実行して系統的にシャットダウンを行います。

セッションをクローズすると、関連付けられているすべてのプロデューサとコンシューマもクローズされます。

注意: onMessage() メソッド呼び出し内で close() メソッドを発行する場合、システム管理者は接続ファクトリをコンフィグレーションするときに [メッセージの短縮を許可] チェック ボックスを選択しなければなりません。詳細については、Administration Console オンライン ヘルプの「[JMS 接続ファクトリ]」を参照してください。

 


送り先の動的作成

以下のいずれかを使用して、送り先を動的に作成できます。

送り先の動的作成に関する手順については、以降の節で説明します。

JMSHelper クラス メソッドの使い方

以下の各 JMSHelper メソッドを使用してキューまたはトピックを作成する非同期リクエストを動的に送信できます。

static public void createPermanentQueueAsync(
Context ctx,
String jmsServerName,
String queueName,
String jndiName
) throws JMSException
static public void createPermanentTopicAsync(
Context ctx,
String jmsServerName,
String topicName,
String jndiName
) throws JMSException

JNDI 初期コンテキスト、送り先に関連付けられる JMS サーバの名前、送り先 (キューまたはトピック) の名前、および JNDI ネームスペース内で送り先をルックアップする場合に使用する名前を指定する必要があります。

各メソッドによって、以下のものが更新されます。

注意: いずれのメソッド呼び出しも、例外を送出せずに失敗する場合があります。また、例外が送出されても、それが必ずしもメソッド呼び出しの失敗を示しているとは限りません。

JMS サーバでの送り先の作成と JNDI ネームスペースへの情報の伝播には、時間がかかる場合があります。複数のサーバを使用している環境では、伝播の遅延が増大します。JNDI ルックアップを実行するよりも、createQueue() メソッドまたは createTopic() メソッドを使用して、それぞれキューまたはトピックの存在をテストすることをお勧めします。この方法によって、伝播固有の遅延を、ある程度回避できます。

たとえば、次に示す findQueue() メソッドは、動的に作成されたキューにアクセスしようとしますが、アクセスに失敗すると再試行まで、指定された間隔スリープします。無限ループを回避するために、再試行の最大回数が設定されています。

private static Queue findQueue (
QueueSession queueSession,
String jmsServerName,
String queueName,
int retryCount,
long retryInterval
) throws JMSException
{
String wlsQueueName = jmsServerName + "/" + queueName;
String command = "QueueSession.createQueue(" +
wlsQueueName + ")";
long startTimeMillis = System.currentTimeMillis();
for (int i=retryCount; i>=0; i--) {
try {
System.out.println("Trying " + command);
Queue queue = queueSession.createQueue(wlsQueueName);
System.out.println(command + "succeeded after " +
(retryCount - i + 1) + " tries in " +
(System.currentTimeMillis() - startTimeMillis) +
" millis.");
return queue;
} catch (JMSException je) {
if (retryCount == 0) throw je;
}
try {
System.out.println(command + “> failed, pausing “ +
retryInterval + " millis.");
Thread.sleep(retryInterval);
} catch (InterruptedException ignore) {}
   }
throw new JMSException("out of retries");
}

この場合、JMSHelper クラス メソッドの後に findQueue() メソッドを呼び出すことで、動的に作成されたキューを使用可能になりしだい、取り出すことができます。次に例を示します。

JMSHelper.createPermanentQueueAsync(ctx, domain, jmsServerName,
queueName, jndiName);
Queue queue = findQueue(qsess, jmsServerName, queueName,
retry_count, retry_interval);

JMSHelper クラスの詳細については、weblogic.jms.extensions.JMSHelper Javadoc を参照してください。

一時的な送り先の使い方

一時的な送り先を使用することで、サーバ定義の送り先のコンフィグレーションと作成に伴うシステム管理のオーバーヘッドを発生させずに、必要に応じてアプリケーションで送り先を作成できます。

WebLogic JMS サーバでは、JMSReplyTo ヘッダ フィールドを使用して、アプリケーションに応答を返すことができます。アプリケーションでは、オプションとして、メッセージの JMSReplyTo ヘッダ フィールドをその一時的な送り先に設定することで、使用している一時的な送り先を別のアプリケーションに対して公開できます。

一時的な送り先は、一時的な送り先の削除にある説明のとおりに delete() メソッドを使用して削除されない限り、現在の接続が継続している間だけ存在します。

サーバが再起動されると、メッセージは使用できなくなるので、すべての PERSISTENT メッセージは自動的に NON_PERSISTENT メッセージになります。そのため、一時的な送り先は、再起動によるデータの消失が許されないビジネス ロジックには適していません。

注意: 一時的な送り先 (キューまたはトピック) を作成する前に、Administration Console を使用して、一時的な送り先を使用する JMS サーバをコンフィグレーションする必要があります。そのためには、JMS サーバの Temporary Template 属性を使用して、同じドメイン内でコンフィグレーションされる JMS テンプレートを選択します。JMS サーバのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「[JMS サーバ]」を参照してください。

以降の節では、一時的なキュー (PTP) または一時的なトピック (Pub/Sub) の作成方法について説明します。

一時的なキューの作成

次の QueueSession メソッドを使用して、一時的なキューを作成できます。

public TemporaryQueue createTemporaryQueue(
) throws JMSException

たとえば、現在の接続が継続している間だけ存在する TemporaryQueue への参照を作成するには、次のメソッド呼び出しを使用します。

QueueSender = Session.createTemporaryQueue();

一時的なトピックの作成

次の TopicSession メソッドを使用して、一時的なトピックを作成できます。

public TemporaryTopic createTemporaryTopic(
) throws JMSException

たとえば、現在の接続が継続している間だけ存在する一時的なトピックへの参照を作成するには、次のメソッド呼び出しを使用します。

TopicPublisher = Session.createTemporaryTopic();

一時的な送り先の削除

一時的な送り先の使用が終了したら、次の TemporaryQueue メソッドまたは TemporaryTopic メソッドを使用して送り先を削除し、関連リソースを解放できます。

public void delete(
) throws JMSException

 


恒久サブスクリプションの設定

WebLogic JMS では、恒久サブスクリプションおよび非恒久サブスクリプションがサポートされています。

恒久サブスクリプションの場合、WebLogic JMS では、メッセージはサブスクライバに配信されるか、または期限切れになるまで永続ファイルまたはデータベースに格納されます。この場合、メッセージの配信時にサブスクライバがアクティブな状態でなくてもかまいません。サブスクライバを表す Java オブジェクトが存在していれば、サブスクライバはアクティブであるとみなされます。恒久サブスクリプションは、Pub/Sub メッセージングのみでサポートされています。

注意: 恒久サブスクリプションは、分散トピックに対しては作成できません。ただし、分散トピックのメンバーに対して恒久サブスクリプションを作成することはできます。こうすると、他のトピック メンバーは、恒久サブスクリプションを持つメンバーにメッセージを転送します。分散トピックの使い方の詳細については、分散送り先の使用を参照してください。

非恒久サブスクリプションの場合、WebLogic JMS では、メッセージはアクティブ セッションを持つアプリケーションにのみ配信されます。アプリケーションがリスンしていない間にトピックへ送信されたメッセージは、二度とそのアプリケーションに配信されません。つまり、非恒久サブスクリプションは、そのサブスクライバ オブジェクトが存在している間だけ存続します。デフォルトでは、サブスクライバは非恒久です。

以降の節で説明する内容は、次のとおりです。

クライアント ID の定義

恒久サブスクリプションをサポートするには、接続に対してクライアント ID を定義する必要があります。

注意: JMS クライアント ID は、WebLogic セキュリティ レルムでのユーザ認証で使用される WebLogic Server ユーザ名とは必ずしも一致しません。JMS アプリケーションに適合していれば、JMS クライアント ID を WebLogic Server ユーザ名に設定することは当然可能です。

クライアント ID は、以下の 2 つの方法で設定できます。

注意: 恒久サブスクリプションのサポートは、Pub/Sub メッセージング モデル固有の機能なので、クライアント ID はトピック接続でしか使用できません。キュー接続にもクライアント ID がありますが、JMS では使用されません。

恒久サブスクリプションは、一時的なトピックに対しては作成しないでください。一時的なトピックは、現在の接続が継続している間だけ存在するように設計されているからです。

恒久サブスクリプション用のサブスクライバの作成

以下の TopicSession メソッドを使用して、恒久サブスクリプション用のサブスクライバを作成できます。

public TopicSubscriber createDurableSubscriber(
Topic topic,
String name
) throws JMSException
public TopicSubscriber createDurableSubscriber(
Topic topic,
String name,
String messageSelector,
boolean noLocal
) throws JMSException

サブスクライバを作成するトピックの名前と恒久サブスクリプションの名前を指定する必要があります。また、メッセージをフィルタ処理するためのメッセージ セレクタ、および noLocal フラグ (この節で後述) を指定することもできます。メッセージ セレクタの詳細については、メッセージのフィルタ処理を参照してください。messageSelector を指定しない場合、デフォルトではすべてのメッセージが検索されます。

アプリケーションでは、JMS 接続を使用して同じトピックに対してパブリッシュとサブスクライブの両方を行うことができます。トピック メッセージはすべてのサブスクライバに配信されるので、アプリケーションは自身がパブリッシュしたメッセージを受信する可能性があります。これを防ぐために、JMS アプリケーションは noLocal フラグを true に設定できます。noLocal 値は、デフォルトでは false になっています。

恒久サブスクリプション名は、クライアント ID ごとにユニークである必要があります。接続に対するクライアント ID の定義については、クライアント ID の定義を参照してください。

特定の恒久サブスクリプション用のサブスクライバをいつでも定義できるのは、1 つのセッションだけです。複数のサブスクライバが恒久サブスクリプションにアクセスできますが、同時にはアクセスできません。恒久サブスクリプションはファイルまたはデータベースに格納されます。

恒久サブスクリプションの削除

恒久サブスクリプションを削除するには、次の TopicSession メソッドを使用します。

public void unsubscribe(
String name
) throws JMSException

削除する恒久サブスクリプションの名前を指定する必要があリます。

以下の条件のいずれかに当てはまる場合は、恒久サブスクリプションを削除できません。

注意: Administration Console を使用して恒久サブスクリプションを削除することもできます。恒久サブスクリプションの管理の詳細については、恒久サブスクリプションの管理を参照してください。

恒久サブスクリプションの変更

恒久サブスクリプションを変更するには、以下の手順を実行します。

  1. 恒久サブスクリプションの削除にある説明に従って、恒久サブスクリプションを削除します。

    この手順は省略可能です。この手順が明示的に実行されない場合は、次の手順で恒久サブスクリプションが再作成されるときに暗黙的に削除が行われます。

  2. 恒久サブスクリプション用のサブスクライバの作成で説明されているメソッドを使用して、同じ名前の恒久サブスクリプションを再作成します。ただし、トピック名、メッセージ セレクタ、noLocal のいずれかには異なる値を指定します。

    新しい値に基づいて、恒久サブスクリプションが再作成されます。

注意: 恒久サブスクリプションを再作成する場合には、重複した名前を持つ恒久サブスクリプションを作成しないよう注意してください。たとえば、使用できない JMS サーバから恒久サブスクリプションを削除しようとすると、削除は失敗します。続いて、別の JMS サーバで同じ名前の恒久サブスクリプションを作成すると、最初の JMS サーバが使用可能になったときに予期しない結果が生じることがあります。元の恒久サブスクリプションが削除されていないため、最初の JMS サーバが再び使用可能になると、重複した名前の 2 つの恒久サブスクリプションが存在することになります。

恒久サブスクリプションの管理

Administration Console を使用して恒久サブスクリプションをモニタおよび削除することができます。詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

 


メッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドの設定と参照

WebLogic JMS には、メッセージの識別および転送を定義できる一連の標準ヘッダ フィールドが用意されています。さらに、プロパティ フィールドを使用すると、標準セットを拡張した、アプリケーション固有のヘッダ フィールドをメッセージ内に含めることができます。メッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドを使用して、通信しているプロセス間で情報をやり取りできます。

データをメッセージ本文ではなくプロパティ フィールドに含める主要な理由は、メッセージ セレクタを使用したメッセージのフィルタ処理をサポートするためです。メッセージ セレクタからは、メッセージ本文のデータにはアクセスできません。たとえば、プロパティ フィールドを使用して、あるメッセージに高い優先度を割り当てると仮定します。その場合、このプロパティ フィールドにアクセスし、至急の優先度が指定されたメッセージだけを選択するメッセージ セレクタを含むメッセージ コンシューマを作成できます。セレクタの詳細については、メッセージのフィルタ処理を参照してください。

メッセージ ヘッダ フィールドの設定

JMS メッセージには、常にメッセージと共に送信されるヘッダ フィールドの標準セットが含まれます。これらはメッセージを受信するメッセージ コンシューマで利用でき、また、一部のフィールドはメッセージを送信するメッセージ プロデューサで設定できます。メッセージを受信したら、ヘッダ フィールドの値は変更できます。

標準メッセージ ヘッダ フィールドの詳細については、メッセージ ヘッダ フィールドを参照してください。

次の表に、Message クラスの set メソッドと get メソッドを、サポートされているデータ型ごとに示します。

注意: set() メソッドを使用して設定されたヘッダ フィールド値は、send() メソッドによってオーバーライドされる場合もあります (次表参照)。

ヘッダ フィールド

set メソッド

get メソッド

JMSCorrelationID

public void setJMSCorrelationID(
String correlationID
) throws JMSException

public String getJMSCorrelationID(
) throws JMSException


public byte[] getJMSCorrelationIDAsBytes(
) throws JMSException

JMSDestination
1. 

public void setJMSDestination(
Destination destination
) throws JMSException

public Destination getJMSDestination(
) throws JMSException

JMSDeliveryMode1

public void setJMSDeliveryMode(
int deliveryMode
) throws JMSException

public int getJMSDeliveryMode(
) throws JMSException

JMSDeliveryTime1

public void setJMSDeliveryTime(
long deliveryTime
) throws JMSException

public long getJMSDeliveryTime(
) throws JMSException

JMSDeliveryMode1

public void setJMSDeliveryMode(
int deliveryMode
) throws JMSException

public int getJMSDeliveryMode(
) throws JMSException

JMSMessageID1

public void setJMSMessageID(
String id
) throws JMSException

set メソッドだけでなく、weblogic.jms.extensions.JMSHelper クラスには、WebLogic JMS 6.0 以前の JMSMessageID 形式を WebLogic JMS 6.1 の形式に (または WebLogic JMS 6.1 の形式をそれ以前の形式に) 変換する、以下のメソッドも用意されている。
public void oldJMSMessageIDToNew(
String id,
long timeStamp
) throws JMSException

public void newJMSMessageIDToOld(
String id,
long timeStamp
) throws JMSException

public String getJMSMessageID(
) throws JMSException

JMSPriority1

public void setJMSPriority(
int priority
) throws JMSException

public int getJMSPriority(
) throws JMSException

JMSRedelivered1

public void setJMSRedelivered(
boolean redelivered
) throws JMSException

public boolean getJMSRedelivered(
) throws JMSException

JMSReplyTo

public void setJMSReplyTo(
Destination replyTo
) throws JMSException

public Destination getJMSReplyTo(
) throws JMSException

JMSTimeStamp1

public void setJMSTimeStamp(
long timestamp
) throws JMSException

public long getJMSTimeStamp(
) throws JMSException

JMSType

public void setJMSType(
String type
) throws JMSException

public String getJMSType(
) throws JMSException

1send() メソッドが実行されている場合、対応する set() メソッドは、メッセージ ヘッダ フィールドに影響を与えません。ヘッダ フィールド値が設定されている場合は、send() メソッドの処理中に、このヘッダ フィールド値がオーバーライドされます。

WL_HOME¥samples¥server¥src¥examples¥jms¥sender ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) に収められている WebLogic Server 付属の examples.jms.sender.SenderServlet の例では、送信するメッセージのヘッダ フィールドを設定する方法、および送信後にメッセージのヘッダ フィールドを表示する方法を示します。

たとえば、send() メソッドの後に置く、次のコードは、WebLogic JMS によってメッセージに割り当てられたメッセージ ID を表示します。

System.out.println("Sent message " +
msg.getJMSMessageID() + " to " +
msg.getJMSDestination());

メッセージ プロパティ フィールドの設定

プロパティ フィールドを設定するには、適切な set メソッドを呼び出して、プロパティ名と値を指定します。プロパティ フィールドを参照するには、適切な get メソッドを呼び出して、プロパティ名を指定します。

送信側アプリケーションはメッセージにプロパティを設定でき、受信側アプリケーションはそのプロパティを表示できます。受信側アプリケーションがプロパティを変更するには、まず次の clearProperties() メソッドを使用してプロパティを消去する必要があります。

public void clearProperties(
) throws JMSException

このメソッドは、メッセージ ヘッダ フィールドおよびメッセージ本文は消去しません。

注意: JMS 用に JMSX というプロパティ名のプレフィックスが予約されています。接続メタデータには、JMSX プロパティのリストが含まれています。getJMSXPropertyNames() メソッドを使用して、列挙リストとして、このリストにアクセスできます。詳細については、接続メタデータへのアクセスを参照してください。

プロバイダ固有のプロパティ用に JMS_ というプロパティ名のプレフィックスが予約されています。このプレフィックスは標準の JMS メッセージングでは使用できません。

プロパティ フィールドは、boolean、byte、double、float、int、long、short、string の各データ型のいずれかに設定できます。次の表に、Message クラスの set メソッドと get メソッドを、サポートされているデータ型ごとに示します。

表4-4 メッセージ プロパティのデータ型ごとの set メソッドおよび get メソッド

データ型

set メソッド

get メソッド

boolean

public void setBooleanProperty(
String name,
boolean value
) throws JMSException

public boolean getBooleanProperty(
String name
) throws JMSException

byte

public void setByteProperty(
String name,
byte value
) throws JMSException

public byte getByteProperty(
String name
) throws JMSException

double

public void setDoubleProperty(
String name,
double value
) throws JMSException

public double getDoubleProperty(
String name
) throws JMSException

float

public void setFloatProperty(
String name,
float value
) throws JMSException

public float getFloatProperty(
String name
) throws JMSException

int

public void setIntProperty(
String name,
int value
) throws JMSException

public int getIntProperty(
String name
) throws JMSException

long

public void setLongProperty(
String name,
long value) throws JMSException

public long getLongProperty(
String name
) throws JMSException

short

public void setShortProperty(
String name,
short value
) throws JMSException

public short getShortProperty(
String name
) throws JMSException

String

public void setStringProperty(
String name,
String value
) throws JMSException

public String getStringProperty(
String name
) throws JMSException


上記の表で説明した set メソッドおよび get メソッド以外にも、setObjectProperty() メソッドおよび getObjectProperty() メソッドを使用して、プロパティのデータ型の具体的なプリミティブ値を使用できます。具体的な値が使用されている場合、プロパティのデータ型はコンパイル時ではなく、実行時に決定されます。有効なオブジェクトのデータ型は、boolean、byte、double、float、int、long、short、および string です。

次の Message メソッドを使用して、すべてのプロパティ フィールド名にアクセスできます。

public Enumeration getPropertyNames(
) throws JMSException

このメソッドは、すべてのプロパティ フィールド名を列挙して返します。その後、プロパティ フィールドのデータ型に基づいて、上記の表で説明されている適切な get メソッドにプロパティ フィールド名を渡すことで、各プロパティ フィールドの値を取り出すことができます。

次の表は、メッセージ プロパティの変換表です。この表から、読み込み可能なデータ型を、書き込まれたデータ型に基づいて識別できます。

表4-5 メッセージ プロパティの変換表

書き込まれたプロパティのデータ型 . .

読み込み可能なデータ型 . .

boolean

byte

double

float

int

long

short

String

boolean

X







X

byte


X



X

X

X

X

double



X





X

float



X

X




X

int





X

X


X

long






X


X

Object

X

X

X

X

X

X

X

X

short





X

X

X

X

String

X

X

X

X

X

X

X

X


次の Message メソッドを使用して、プロパティの値が設定されているかどうかをテストできます。

public boolean propertyExists(
String name
) throws JMSException

プロパティ名を指定すると、メソッドはそのプロパティが存在するかどうかを示すブール値を返します。

たとえば、次のコードは、2 種類の String プロパティと 1 種類の int プロパティを設定します。

msg.setStringProperty("User", user);
msg.setStringProperty("Category", category);
msg.setIntProperty("Rating", rating);

メッセージ プロパティ フィールドの詳細については、メッセージ プロパティ フィールド、またはja vax.jms.Message Javadoc を参照してください。

メッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドの参照

注意: 参照できるのは、キューのメッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドだけです。トピックのメッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドは参照できません。

以下の QueueSession メソッドを使用して、キューにあるメッセージのヘッダ フィールドおよびプロパティ フィールドを参照できます。

public QueueBrowser createBrowser(
Queue queue
) throws JMSException
public QueueBrowser createBrowser(
Queue queue,
String messageSelector
) throws JMSException

参照するキューを指定する必要があります。また、参照するメッセージをフィルタ処理するメッセージ セレクタを指定することもできます。メッセージ セレクタの詳細については、メッセージのフィルタ処理を参照してください。

キューを定義すると、以下の QueueBrowser メソッドを使用して、キュー ブラウザに関連付けられたキュー名およびメッセージ セレクタにアクセスできるようになります。

public Queue getQueue(
) throws JMSException
public String getMessageSelector(
) throws JMSException

さらに、次の QueueBrowser メソッドを使用して、メッセージを参照するための列挙値にアクセスできます。

public Enumeration getEnumeration(
) throws JMSException

WL_HOME¥samples¥server¥src¥examples¥jms¥queue ディレクトリ (WL_HOME は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.queue.QueueBrowser の例では、受信されたメッセージのヘッダ フィールドにアクセスする方法を示します。

たとえば、次の QueueBrowser の例からの引用コードでは、QueueBrowser オブジェクトを作成します。

qbrowser = qsession.createBrowser(queue);

次のコードは、QueueBrowser の例で定義されている displayQueue() メソッドからの引用です。この例では、QueueBrowser オブジェクトを使用して、キューのメッセージをスキャンする場合に使用される列挙値を取得します。

   public void displayQueue(
) throws JMSException
{
Enumeration e = qbrowser.getEnumeration();
Message m = null;

if (! e.hasMoreElements()) {
System.out.println("There are no messages on this queue.");
} else {
      System.out.println("Queued JMS Messages: ");
while (e.hasMoreElements()) {
m = (Message) e.nextElement();
System.out.println("Message ID " + m.getJMSMessageID() +
" delivered " + new Date(m.getJMSTimestamp())
" to " + m.getJMSDestination());
}
}

キュー ブラウザが使用されていない場合は、キュー ブラウザを閉じてリソースを解放する必要があります。詳細については、オブジェクト リソースの解放を参照してください。

QueueBrowser クラスの詳細については、javax.jms.QueueBrowser Javadoc を参照してください。

 


メッセージのフィルタ処理

多くの場合、アプリケーションでは、配信されるすべてのメッセージが通知される必要はありません。メッセージ セレクタを使用すると、不要なメッセージをフィルタ処理できるので、ネットワーク トラフィックへの影響が最小限になり、パフォーマンスが向上します。

メッセージ セレクタは、以下のように動作します。

メッセージ セレクタはメッセージの内容 (本文) を参照することができないため、情報の一部をメッセージ プロパティ フィールドに複製することもできます (XML メッセージの場合を除く)。

キュー レシーバまたはトピック サブスクライバの作成時に、それぞれ QueueSession.createReceiver() メソッドまたは TopicSession.createSubscriber() メソッドの引数としてセレクタを指定します。キュー レシーバまたはトピック サブスクライバの作成の詳細については、手順 5 :セッションと送り先を使用してメッセージ プロデューサとメッセージ コンシューマを作成するを参照してください。

以降の節では、SQL 文と XML セレクタ メソッドを使用してメッセージ セレクタを定義する方法、およびメッセージ セレクタを更新する方法について説明します。ヘッダ フィールドおよびプロパティ フィールドの設定の詳細については、それぞれメッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドの設定と参照、またはメッセージ プロパティ フィールドの設定を参照してください。

SQL 文を使用したメッセージ セレクタの定義

メッセージ セレクタはブール式であり、SQLselect 文の where 句と似た構文を持つ文字列です。

次の引用は、セレクタ式の例を示します。

salary > 64000 and dept in ('eng','qa')
(product like 'WebLogic%' or product like '%T3')
and version > 3.0
hireyear between 1990 and 1992
or fireyear is not null
fireyear - hireyear > 4

次の例では、キュー レシーバの作成時に、優先度が 6 未満のメッセージをフィルタで除外するセレクタを設定する方法を示します。

String selector = "JMSPriority >= 6";
qsession.createReceiver(queue, selector);

次の例では、トピック サブスクライバの作成時に、同様のセレクタを設定する方法を示します。

String selector = "JMSPriority >= 6";
qsession.createSubscriber(topic, selector);

メッセージ セレクタの構文の詳細については、javax.jms.Message Javadoc を参照してください。

XML セレクタ メソッドを使用した XML メッセージ セレクタの定義

XML メッセージ タイプの場合、メッセージ セレクタの定義には、前節で説明した SQL セレクタ式だけでなく、次のメソッドを使用することもできます。

String JMS_BEA_SELECT(String type, String expression)

JMS_BEA_SELECT は、WebLogic JMS SQL 構文の組み込み関数です。構文タイプと XPath 式を指定します。構文タイプは、xpath (XML Path Language) に設定する必要があります。XML Path Language は、XML Path Language (XPath) のドキュメントで定義されており、XML Path Language の Web サイト http://www.w3.org/TR/xpath で入手できます。

以下の環境では、メソッドは null 値を返します。

たとえば、次のような XML の引用があります。

<order>
<item>
<id>007</id>
<name>Hand-held Power Drill</name>
<description>Compact, assorted colors.</description>
<price>$34.99</price>
</item>
<item>
<id>123</id>
<name>Mitre Saw</name>
<description>Three blades sizes.</description>
<price>$69.99</price>
</item>
<item>
<id>66</id>
<name>Socket Wrench Set</name>
<description>Set of 10.</description>
<price>$19.99</price>
</item>
</order>

次の例では、上記の引用にある 2 番目の項目の名前を取り出す方法を示します。メソッド呼び出しは、Mitre Saw という文字列を返します。

String sel = "JMS_BEA_SELECT('xpath', '/order/item[2]/name/text()') = 'Mitre Saw'";

二重引用符と単一引用符、およびスペースの使い方に注意してください。xpath、XML タブ、および文字列値が単一引用符で囲まれていることに注意してください。

次の例では、上記の引用にある 3 番目の項目の ID を取り出す方法を示します。メソッド呼び出しは、66 という文字列を返します。

String sel = "JMS_BEA_SELECT('xpath', '/order/item[3]/id/text()') = '66'";

メッセージ セレクタの表示

次の MessageConsumer メソッドを使用して、メッセージ セレクタを表示できます。

public String getMessageSelector(
) throws JMSException

このメソッドは、現在定義されているメッセージ セレクタ、またはメッセージ セレクタが定義されていない場合は null のいずれかを返します。

トピック サブスクライバのメッセージ セレクタにインデックスを付けることによるパフォーマンスの最適化

アプリケーションの一部のクラスでは、WebLogic JMS でトピック サブスクライバのメッセージ セレクタにインデックスを付けることで最適化できます。一般的にこれらのアプリケーションは、各々がユニークな識別子 (ユーザ名など) を付けられた多数のサブスクライバを備えており、単一のサブスクライバ、またはサブスクライバのリストに対し、迅速にメッセージを送信できる必要があります。一般的な例としては、各サブスクライバが異なるユーザに対応し、各メッセージに 1 つまたは複数の対象ユーザのリストが含まれるインスタント メッセージング アプリケーションがあります。

最適化されたサブスクライバのメッセージ セレクタをアクティブ化するには、サブスクライバはセレクタに対し次の構文を使用する必要があります。

"identifier IS NOT NULL"

ここで、identifier はあらかじめ定義された JMS メッセージ プロパティではない (例 : JMSCorrelationID でも JMSType でもない) 任意の文字列を表します。複数のサブスクライバで同一の識別子を共有できます。

WebLogic JMS はこのメッセージ セレクタ構文を、内部サブスクライバ インデックスを構築する手掛かりとして使用します。この構文に従わないメッセージ セレクタ、またはさらに OR 句および AND 句を含むメッセージ セレクタにも対応はしていますが、これらは最適化にはつながりません。

サブスクライバがこのメッセージ セレクタ構文を使って登録を行った後は、トピックに公開されたメッセージが、次の例のようにメッセージのユーザ プロパティに 1 つまたは複数の識別子を含めることによって、特定のサブスクライバを対象とできるようになります。

// 指定されたサブスクライバを設定する。ここでは "wilma" が
// サブスクライバ名、subscriberSession は JMS TopicSession。
// 使用されているセレクタ構文により、最適化が促進される。
TopicSubscriber topicSubscriber =
subscriberSession.createSubscriber(
(Topic)context.lookup("IMTopic"),
"Wilma IS NOT NULL",
/* noLocal= */ true);
// サブスクライバ "Fred" および "Wilma" へメッセージを送信する。
// ここでは publisherSession は JMS TopicSession。メッセージ
// セレクタ式が "Wilma IS NOT NULL" または "Fred IS NOT NULL" である
// サブスクライバが、このメッセージを受信する。
TopicPublisher topicPublisher = 
publisherSession.createPublisher(
(Topic)context.lookup("IMTopic");
TextMessage msg = 
publisherSession.createTextMessage("Hi there!");
msg.setBooleanProperty("Fred", true);
msg.setBooleanProperty("Wilma", true);
topicPublisher.publish(msg);

注意:

最適化されたメッセージ セレクタおよびメッセージ構文は、標準 JMS API に基づいています。したがって、この構文を使用するアプリケーションは、最適化されたメッセージ セレクタのないバージョンの WebLogic JMS および非 WebLogic JMS 製品でも機能します。ただし、これらのバージョンでは、この機能強化が含まれているバージョンほどのパフォーマンスは得られません。

メッセージ セレクタの最適化は、MULTICAST_NO_ACKNOWLEDGE 確認応答モードを使用するアプリケーションには効果がありません。メッセージ選択はサーバ サイドではなくクライアント サイドで行われるため、これらのアプリケーションはいずれにしても機能強化を必要としません。

 


サーバ セッション プールの定義

WebLogic JMS には、サーバ セッションのサーバ管理プールを定義するためのオプションの JMS 機能が実装されています。この機能を使用すると、アプリケーションで複数のメッセージを並行して処理できます。

サーバ セッション プールの機能は次のとおりです。

次の図に、サーバ セッション プール機能、およびアプリケーションとアプリケーション サーバのコンポーネントの関係を示します。

図4-3 サーバ セッション プール機能


 

図に示されているように、アプリケーションにはシングル スレッドのメッセージ リスナが用意されています。JMS によって実装された、アプリケーション サーバ上の接続コンシューマによって、以下のタスクが実行され、1 つまたは複数のメッセージが処理されます。

  1. サーバ セッション プールからサーバ セッションを取得する。

  2. サーバ セッションのセッションを取得する。

  3. セッションに 1 つまたは複数のメッセージをロードする。

  4. サーバ セッションを開始して、メッセージを受信する。

  5. メッセージの処理が終了したら、サーバ セッションを解放してプールに戻す。

次の図に、メッセージの並行処理を行うための準備に必要な手順を示します。

図4-4 メッセージの並行処理を行うための準備


 


 

この手順では、アプリケーションで、他のアプリケーション サーバ プロバイダのセッション プール実装を使用できます。サーバ セッション プールはメッセージ駆動型 Bean を使用して実装することもできます。メッセージ駆動型 Bean によるサーバ セッション プールの実装については、『WebLogic エンタープライズ JavaBeans プログラマーズ ガイド』を参照してください。

コンフィグレーション時にセッション プールと接続コンシューマが定義された場合は、この手順を省略することができます。サーバ セッション プールと接続コンシューマのコンフィグレーションの詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

WebLogic JMS は現在、オプションの TopicConnection.createDurableConnectionConsumer() 操作をサポートしていません。この高機能 JMS の操作の詳細については、Sun Microsystems の JMS 仕様を参照してください。

手順 1 :JNDI でサーバ セッション プール ファクトリをルックアップする

サーバ セッション プール ファクトリを使用して、サーバ セッション プールを作成します。

WebLogic JMS は、デフォルトでは weblogic.jms.ServerSessionPoolFactory:<name> (<name> は、セッション プールが作成される JMS サーバ名) という ServerSessionPoolFactory オブジェクトを 1 つ定義します。

コンフィグレーションが終了したら、サーバ セッション プール ファクトリをルックアップするために、まずNam ingManager.InitialContext() メソッドを使用して JNDI コンテキスト (context) を定義します。サーブレット アプリケーション以外のアプリケーションの場合は、初期コンテキストの作成に使用する環境を渡す必要があります。詳細については、NamingManager.InitialContext() Javadoc を参照してください。

コンテキストが定義されたら、次のコードを使用して、JNDI でサーバ セッション プール ファクトリをルックアップします。

factory = (ServerSessionPoolFactory) context.lookup(<ssp_name>);

<ssp_name> には、サーバ セッション プール ファクトリの修飾名または非修飾名を指定します。

サーバ セッション プール ファクトリの詳細については、ServerSessionPoolFactory、または weblogic.jms.ServerSessionPoolFactory Javadoc を参照してください。

手順 2 :サーバ セッション プール ファクトリを使用してサーバ セッション プールを作成する

以降の節で説明する ServerSessionPoolFactory メソッドを使用して、キュー (PTP) またはトピック (Pub/Sub) の接続コンシューマで使用するサーバ セッション プールを作成できます。

サーバ セッション プールの詳細については、ServerSessionPool、または javax.jms.ServerSessionPool Javadoc を参照してください。

キュー接続コンシューマで使用するサーバ セッション プールを作成する

ServerSessionPoolFactory には、キュー接続コンシューマ用のサーバ セッション プールを作成する、次のメソッドが用意されています。

public ServerSessionPool getServerSessionPool(
QueueConnection connection,
int maxSessions,
boolean transacted,
int ackMode,
String listenerClassName
) throws JMSException

サーバ セッション プールに関連付けられるキュー接続、接続コンシューマ (手順 3 で作成予定) で取得できる並行セッションの最大数、セッションをトランザクション処理するかどうか、確認応答モード (トランザクション処理されないセッションの場合にのみ適用可能)、およびインスタンス化され、メッセージの受信および並行処理に使用されるメッセージ リスナ クラスを指定する必要があります。

ServerSessionPoolFactory クラス メソッドの詳細については、weblogic.jms.ServerSessionPoolFactoryJavadoc を参照してください。ConnectionConsumer クラスの詳細については、javax.jms.ConnectionConsumer Javadoc を参照してください。

トピック接続コンシューマで使用するサーバ セッション プールを作成する

ServerSessionPoolFactory には、トピック接続コンシューマ用のサーバ セッション プールを作成する、次のメソッドが用意されています。

public ServerSessionPool getServerSessionPool(
TopicConnection connection,
int maxSessions,
boolean transacted,
int ackMode,
String listenerClassName
) throws JMSException

サーバ セッション プールに関連付けられるトピック接続、接続コンシューマ (手順 3 で作成予定) で取得できる並行セッションの最大数、セッションをトランザクション処理するかどうか、確認応答モード (トランザクション処理されないセッションの場合にのみ適用可能)、およびインスタンス化され、メッセージの受信および並行処理に使用されるメッセージ リスナ クラスを指定する必要があります。

ServerSessionPoolFactory クラス メソッドの詳細については、weblogic.jms.ServerSessionPoolFactoryJavadoc を参照してください。ConnectionConsumer クラスの詳細については、javax.jms.ConnectionConsumer Javadoc を参照してください。

手順 3 : 接続コンシューマを作成する

以下の方法のいずれかを使用して、サーバ セッションを取得し、メッセージを並行処理するための接続コンシューマを作成できます。

ConnectionConsumer クラスの詳細については、ConnectionConsumer、またはjav ax.jms.ConnectionConsumer Javadoc を参照してください。

キュー用の接続コンシューマを作成する

QueueConnection には、キュー用の接続コンシューマを作成する、次のメソッドが用意されています。

public ConnectionConsumer createConnectionConsumer(
Queue queue,
String messageSelector,
ServerSessionPool sessionPool,
int maxMessages
) throws JMSException

関連付けられるキューの名前、メッセージをフィルタ処理するためのメッセージ セレクタ、サーバ セッションにアクセスするためのサーバ セッション プール、およびサーバ セッションに同時に割り当てることができるメッセージの最大数を指定する必要があります。メッセージ セレクタの詳細については、メッセージのフィルタ処理を参照してください。

QueueConnection クラス メソッドの詳細については、javax.jms.QueueConnection Javadoc を参照してください。ConnectionConsumer クラスの詳細については、javax.jms.ConnectionConsumer Javadoc を参照してください。

トピック用の接続コンシューマを作成する

TopicConnection には、トピック用の接続コンシューマを作成する、以下の 2 種類のメソッドが用意されています。

public ConnectionConsumer createConnectionConsumer(
Topic topic,
String messageSelector,
ServerSessionPool sessionPool,
int maxMessages
) throws JMSException
public ConnectionConsumer createDurableConnectionConsumer(
Topic topic,
String messageSelector,
ServerSessionPool sessionPool,
int maxMessages
) throws JMSException

各メソッドには、関連付けられるトピックの名前、メッセージをフィルタ処理するためのメッセージ セレクタ、サーバ セッションにアクセスするためのサーバ セッション プール、およびサーバ セッションに同時に割り当てることができるメッセージの最大数を指定する必要があります。メッセージ セレクタの詳細については、メッセージのフィルタ処理を参照してください。

いずれのメソッドも接続コンシューマを作成しますが、後者のメソッドは、恒久サブスクライバで使用する恒久接続コンシューマも作成します。恒久サブスクライバの詳細については、恒久サブスクリプションの設定を参照してください。

TopicConnection クラス メソッドの詳細については、javax.jms.TopicConnection Javadoc を参照してください。ConnectionConsumer クラスの詳細については、javax.jms.ConnectionConsumer Javadoc を参照してください。

例 :PTP クライアントのサーバ セッション プールの設定

次の例では、JMS クライアント用のサーバ セッション プールを設定する方法を示します。startup() メソッドは、例 :PTP アプリケーションの設定で説明されている examples.jms.queue.QueueSend の例の init() メソッドとほぼ同じです。このメソッドでもサーバ セッション プールを設定できます。

次の例に startup() メソッドを示し、併せて各設定手順も述べます。

サーバ セッション プール アプリケーションを実装するには、次のパッケージをインポート リストに追加します。

import weblogic.jms.ServerSessionPoolFactory

セッション プールの作成に必要なセッション プール ファクトリの静的変数を定義します。

private final static String SESSION_POOL_FACTORY=
"weblogic.jms.ServerSessionPoolFactory:examplesJMSServer";

private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private ServerSessionPoolFactory sessionPoolFactory;
private ServerSessionPool sessionPool;
private ConnectionConsumer consumer;

必要な JMS オブジェクトを作成します。

public String startup(
String name,
Hashtable args
) throws Exception
{
String connectionFactory = (String)args.get("connectionFactory");
String queueName = (String)args.get("queue");
if (connectionFactory == null || queueName == null) {
throw new IllegalArgumentException("connectionFactory="+connectionFactory+
", queueName="+queueName);
}
Context ctx = new InitialContext();
qconFactory = (QueueConnectionFactory)
ctx.lookup(connectionFactory);
qcon =qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qcon.start();

手順 1

JNDI でサーバ セッション プール ファクトリをルックアップします。

  sessionPoolFactory = (ServerSessionPoolFactory)
ctx.lookup(SESSION_POOL_FACTORY);

手順 2

次のように、サーバ セッション プール ファクトリを使用してサーバ セッション プールを作成します。

  sessionPool = sessionPoolFactory.getServerSessionPool(qcon, 5,
false, Session.AUTO_ACKNOWLEDGE,
examples.jms.startup.MsgListener);

このコードでは、以下のように定義されています。

手順 3

次のように、接続コンシューマを作成します。

  consumer = qcon.createConnectionConsumer(queue, "TRUE",
sessionPool, 10);

このコードでは、以下のように定義されています。

この例で使用した JMS クラスの詳細については、WebLogic JMS のクラス、または javax.jms Javadoc を参照してください。

例 :Pub/Sub クライアントのサーバ セッション プールの設定

次の例では、JMS クライアント用のサーバ セッション プールを設定する方法を示します。startup() メソッドは、例 :Pub/Sub アプリケーションの設定で説明されている examples.jms.topic.TopicSend の例の init() メソッドとほぼ同じです。このメソッドでもサーバ セッション プールを設定できます。

次の例に startup() メソッドを示し、併せて各設定手順も述べます。

サーバ セッション プール アプリケーションを実装するには、次のパッケージをインポート リストに追加します。

import weblogic.jms.ServerSessionPoolFactory

セッション プールの作成に必要なセッション プール ファクトリの静的変数を定義します。

private final static String SESSION_POOL_FACTORY=
"weblogic.jms.ServerSessionPoolFactory:examplesJMSServer";

private TopicConnectionFactory tconFactory;
private TopicConnection tcon;
private TopicSession tsession;
private TopicSender tsender;
private Topic topic;
private ServerSessionPoolFactory sessionPoolFactory;
private ServerSessionPool sessionPool;
private ConnectionConsumer consumer;

必要な JMS オブジェクトを作成します。

public String startup(
String name,
Hashtable args
) throws Exception
{
String connectionFactory = (String)args.get("connectionFactory");
String topicName = (String)args.get("topic");
if (connectionFactory == null || topicName == null) {
throw new IllegalArgumentException("connectionFactory="+connectionFactory+
", topicName="+topicName);
}
Context ctx = new InitialContext();
tconFactory = (TopicConnectionFactory)
ctx.lookup(connectionFactory);
tcon = tconFactory.createTopicConnection();
tsession = tcon.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = (Topic) ctx.lookup(topicName);
tcon.start();

手順 1

JNDI でサーバ セッション プール ファクトリをルックアップします。

  sessionPoolFactory = (ServerSessionPoolFactory)
ctx.lookup(SESSION_POOL_FACTORY);

手順 2

次のように、サーバ セッション プール ファクトリを使用してサーバ セッション プールを作成します。

  sessionPool = sessionPoolFactory.getServerSessionPool(tcon, 5,
false, Session.AUTO_ACKNOWLEDGE,
examples.jms.startup.MsgListener);

このコードでは、以下のように定義されています。

手順 3

次のように、接続コンシューマを作成します。

  consumer = tcon.createConnectionConsumer(topic, "TRUE",
sessionPool, 10);

このコードでは、以下のように定義されています。

この例で使用した JMS クラスの詳細については、WebLogic JMS のクラス、または javax.jms Javadoc を参照してください。

 


マルチキャストの使い方

マルチキャストを使用することによって、後でメッセージをサブスクライバに転送する、指定したホストのグループにメッセージを配信できます。

マルチキャストには、次のような利点があります。

マルチキャストには、次のような制限があります。

マルチキャストを使用すると便利な例としては、株価表示があります。最新の株価を入手する場合に重要になるのは、信頼性よりもタイムリーな配信です。全部または一部の内容が配信されなくても、リアルタイムの株価情報にアクセスするときに、クライアントは簡単に情報の再送信を要求できます。クライアントでは情報の回復は必要とされません。回復された情報が再配信される頃には、その情報は古くて価値のないものになっています。

次の図に、マルチキャストの設定に必要な手順を示します。

図4-5 マルチキャストの設定


 


 


 

注意: マルチキャストは、Pub/Sub メッセージング モデル、および非恒久サブスクライバのみでサポートされています。

マルチキャスト セッションおよびマルチキャスト コンシューマに関するモニタ統計は提供されません。

マルチキャストを設定する前に、マルチキャストをサポートするよう、次のように接続ファクトリおよび送り先をコンフィグレーションする必要があります。

注意: マルチキャスト IP アドレス、ポート、存続時間の各属性をコンフィグレーションする場合は、ネットワーク管理者に相談してから、適切な値を設定することをお勧めします。

マルチキャストのコンフィグレーション属性の詳細については、Administration Console オンライン ヘルプを参照してください。マルチキャストのコンフィグレーション属性は、コンフィグレーション チェックリスト.でも簡単に説明されています。

手順 1 :JMS アプリケーションを設定し、マルチキャスト セッションとトピック サブスクライバを作成する

JMS アプリケーションの設定については、JMS アプリケーションの設定で説明されています。ただし、セッションを作成する際は、手順 3 :接続を使用してセッションを作成するに説明されているように、acknowledgeMode の値を MULTICAST_NO_ACKNOWLEDGE に設定することで、セッションがマルチキャスト メッセージを受信するように指定します。

注意: マルチキャストは、Pub/Sub メッセージング モデル、および非恒久サブスクライバのみでサポートされています。マルチキャスト セッションで恒久サブスクライバを作成しようとすると、JMSException が送出されます。

たとえば、次のメソッドは、Pub/Sub メッセージング モデル用のマルチキャスト セッションの作成方法を示します。

tsession = tcon.createTopicSession(
false,
WLSession.MULTICAST_NO_ACKNOWLEDGE
);

注意: クライアント サイドでは、マルチキャスト セッションごとに、ソケットからメッセージを取り出すための専用のスレッドが 1 つ必要になります。そのため、JMS クライアントサイドのスレッド プール サイズを増やして調整する必要があります。スレッド プール サイズの調整に関する詳細については、「WebLogic JMS Performance Guide」ホワイト ペーパーの「Tuning Thread Pools and EJB Pools」の項を参照してください。JMS クライアントサイドのスレッド プールのチューニングについて書かれています。

さらに、TopicPublisher と TopicSubscriber の作成にある説明に従って、トピック サブスクライバを作成します。

たとえば、次のコードは、トピック サブスクライバの作成方法を示します。

tsubscriber = tsession.createSubscriber(myTopic);

注意: 指定した送り先がマルチキャストをサポートするようコンフィグレーションされていない場合、createSubscriber() メソッドは失敗します。

手順 2 : メッセージ リスナを設定する

マルチキャストのトピック サブスクライバでは、メッセージを非同期に受信することしかできません。マルチキャスト セッションで同期メッセージを受信しようとすると、JMSException が送出されます。

メッセージの非同期受信にある説明に従って、トピック サブスクライバに対してメッセージ リスナを設定します。

たとえば、次のコードは、メッセージ リスナの設定方法を示します。

tsubscriber.setMessageListener(this);

メッセージを受信すると、WebLogic JMS では、送り先から送信されたメッセージのシーケンスがトラッキングされます。マルチキャスト サブスクライバのメッセージ リスナがシーケンスが異なるメッセージを受信すると、その結果、1 つまたは複数のメッセージがスキップされ、そのセッションの ExceptionListenerSequenceGapException が送出されます。スキップされたメッセージは、その後配信されても破棄されます。たとえば、次の図では、サブスクライバは 2 つの送り先から同時にメッセージを受信しています。

図4-6 マルチキャストにおけるシーケンスのずれ


 

送り先 1 からメッセージ「4」を受信すると、SequenceGapException が送出され、シーケンスが異なるメッセージが受信されたことがアプリケーションに通知されます。その後、メッセージ「3」が配信されても、それは破棄されます。

注意: やり取りされるメッセージ数が多くなるほど、SequenceGapException が発生する危険性も大きくなります。

マルチキャストのコンフィグレーション属性の動的コンフィグレーション

システム管理者は、コンフィグレーション時に、マルチキャストをサポートするよう、各接続ファクトリに対して以下の情報をコンフィグレーションします。

メッセージが最大数に達すると、DataOverrunException が送出され、メッセージは超過時のポリシーに基づいて自動的に破棄されます。また、Session クラスの set メソッドを使用して、最大メッセージ数と超過時のポリシーを設定する方法もあります。

次の表に、Session クラスの set メソッドと get メソッドを、動的コンフィグレーションが可能な属性ごとに示します。

表4-6 メッセージ プロデューサの set メソッドおよび get メソッド

属性

set メソッド

get メソッド

最大メッセージ数

public void setMessagesMaximum(
int messagesMaximum
) throws JMSException

public int getMessagesMaximum(
) throws JMSException

超過時のポリシー

public void setOverrunPolicy (
int overrunPolicy
) throws JMSException

public int getOverrunPolicy(
) throws JMSException

注意: set メソッドを使用して設定された値は、コンフィグレーションされた値よりも優先されます。

Session クラス メソッドの詳細については、weblogic.jms.extensions.WLSession Javadoc を参照してください。マルチキャストのコンフィグレーション属性の詳細については、Administration Console オンライン ヘルプの「JMS の送り先」を参照してください。

例 : マルチキャスト TTL (存続時間)

注意: 次の図は、マルチキャスト TTL (存続時間) 送り先コンフィグレーション属性が、ルータを経由したメッセージの配信に影響する様子を説明するための単純な例です。マルチキャスト TTL 属性をコンフィグレーションする場合は、ネットワーク管理者に相談してから、適切な値を設定することをお勧めします。

マルチキャスト TTL は、メッセージの存続時間に依存しません。

次の例では、マルチキャスト TTL 送り先コンフィグレーション属性が、ルータを経由したメッセージの配信に影響する様子を示します。マルチキャストのコンフィグレーション属性の詳細については、Administration Console オンライン ヘルプの「JMS の送り先」を参照してください。

次のようなネットワーク図があります。

図4-7 マルチキャスト TTL の例


 

この図では、ネットワークは 3 つのサブネットで構成されています。サブネット A にはマルチキャスト パブリッシャがあり、サブネット B および C にはそれぞれ 1 台ずつマルチキャスト サブスクライバがあります。

マルチキャスト TTL 属性が 0 に設定されている (メッセージはルータを経由できず、現在のサブネットにしか配信されないことを示す) 場合は、サブネット A にあるマルチキャスト パブリッシャでメッセージがパブリッシュされても、メッセージはどのマルチキャスト サブスクライバにも配信されません。

マルチキャスト TTL 属性が 1 に設定されている (メッセージは 1 台のルータを経由できることを示す) 場合、サブネット A にあるマルチキャスト パブリッシャでメッセージがパブリッシュされると、サブネット B にあるマルチキャスト サブスクライバでメッセージが受信されます。

同様に、マルチキャスト TTL 属性が 2 に設定されている (メッセージは 2 台のルータを経由できることを示す) 場合、サブネット A にあるマルチキャスト パブリッシャでメッセージがパブリッシュされると、サブネット B および C にあるマルチキャスト サブスクライバでメッセージが受信されます。

 


分散送り先の使用

複数の物理的送り先 (キューとトピック) を単一の分散送り先セットのメンバーとしてコンフィグレーションできるようにすることで、WebLogic JMS は、クラスタ内の 1 台のサーバに障害が発生した場合でもサービスを継続します。適切に構成すると、プロデューサとコンシューマがその分散送り先に対してメッセージを送受信できるようになります。WebLogic JMS は、分散送り先内で利用可能な全送り先メンバーにメッセージの負荷を分散します。サーバの障害で送り先メンバーがアクセスできなくなった場合、トラフィックはセット内の他のアクセス可能な送り先メンバーにリダイレクトされます。

Administration Console を使用して分散送り先をコンフィグレーションする手順については、『管理者ガイド』の「分散送り先のコンフィグレーション」を参照してください。

以下の節では、JMS アプリケーションで分散送り先を使用する方法について説明します。

分散送り先へのアクセス

分散送り先は、実際には一連の物理的な JMS 送り先メンバー (キューまたはトピック) となっており、これには単一の JNDI 名を使用してアクセスします。このため、分散送り先は JNDI を使用してルックアップできます。実装されるインタフェースは javax.jms.Destination で、これはプロデューサ、コンシューマ、およびブラウザの作成に使用できます。

宛先はクラスタ内の複数の WebLogic Server からサービスを受けることができるため、createQueue() メソッドまたは createTopic() メソッドのどちらかを使って送り先の参照を作成するときに提供される名前は、単純に JMSDistributedQueueMBean または JMSDistributedTopicMBean コンフィグレーション MBean 名となります。JMS サーバ名や区切り用のフォワード スラッシュ (/) は必要ありません。

たとえば、次のコードは、分散送り先トピック メンバーのルックアップ方法を示します。

topic = myTopicSession.createTopic("myDistributedTopic");

注意: createQueue() メソッドまたは createTopic() メソッドを呼び出す際、フォワード スラッシュ (/) を含む文字列は、送り先ではなく、分散送り先メンバーの名前であると見なされます。このような分散送り先メンバーが存在しない場合、呼び出しは InvalidDestinationException で失敗します。

分散キューのルックアップ

分散キューは、一連の物理的な JMS キューのメンバーです。したがって、分散キューは QueueSenderQueueReceiver、および QueueBrowser を作成するために使用できます。分散キューが複数の物理的キューを表すという事実は、アプリケーションには全く意識されません。

キューのメンバーはどこにでも配置できますが、単一のサーバ クラスタ内にある JMS サーバからサービスを受ける必要があります。分散キューに送信されるメッセージは、分散キューの一連のメンバー内にある物理的キューの 1 つだけに送られます。キューのメンバーに届いたメッセージは、そのキューのメンバーのコンシューマのみが受信できるようになります。

注意: キューのメンバーがメッセージをキューの他のメンバーに転送できるようにするには、Administration Console の [転送の遅延] 属性をコンフィグレーションします。この属性はデフォルトでは無効になっています。この属性は、コンシューマではなく、メッセージだけを持つ分散キューのメンバーが、コンシューマを持つキューの他のメンバーにメッセージを転送するときに待機する時間を秒単位で定義します。

QueueSender

キュー センダを作成した後、作成時に提供したキューが分散キューであった場合は、センダを使用してメッセージが作成されるたびに、どのキューのメンバーがそのメッセージを受信するかの判断が下されます。各メッセージは単一の物理的キューのメンバーに送信されます。

メッセージが複製されることは一切ありません。このため、メッセージは送信元のキューのメンバーのみから受信できます。メッセージの受信前にその物理的キューが使用できなくなった場合は、そのキューのメンバーがオンラインに復帰するまでこのメッセージを受信できなくなります。

メッセージを分散キューに送信して、その分散キューのキュー レシーバがメッセージを受信することを期待するだけでは十分とは言えません。メッセージは 1 つの物理的キューのメンバーだけに送信されるため、そのキューのメンバーで受信またはリスンするキュー レシーバが存在する必要があります。

注意: コンシューマを持たない分散キューに対するロード バランシングのヒューリスティックについては、ロード バランシングのヒューリスティックを参照してください。

QueueReceiver

キュー レシーバを作成する際は、提供したキューが分散キューの場合、単一の物理的キューのメンバーが作成時にレシーバとして選ばれます。作成された QueueReceiver は、キュー レシーバがキュー メンバーのアクセスを失うまでそのキュー メンバーに固定されます。この時点で、コンシューマは次のように JMSException を受信します。

このような例外を受信した場合、アプリケーションは自分のキュー レシーバを終了し、再作成できます。分散キュー内で他のキュー メンバーを使用できる場合は、新しいキューレシーバが作成され、これらのキュー メンバーのいずれかに固定されます。他のキュー メンバーを使用できない場合、キュー レシーバの再作成はできないため、後で作成を試みる必要があります。

注意: コンシューマを持たない分散キューに対するロード バランシングのヒューリスティックについては、ロード バランシングのヒューリスティックを参照してください。

QueueBrowser

キュー ブラウザを作成する際は、提供されているキューが分散キューの場合、単一の物理的キューのメンバーが作成時にブラウザとして選ばれます。作成されたキュー ブラウザは、レシーバがキュー メンバーのアクセスを失うまでそのキューメンバーに固定されます。その時点でキュー ブラウザを呼び出した場合は、JMSException が発行されます。列挙を呼び出した場合は、NoSuchElementException が返されます。

注意: キュー ブラウザは固定されているキュー メンバーのみを閲覧できます。分散キューが作成時に指定されている場合でも、キュー ブラウザが分散送り先内の他のキュー メンバーのメッセージを表示または閲覧することはできません。

分散トピックのルックアップ

分散トピックは、一連の物理的な JMS トピックのメンバーです。このため、分散トピックは TopicPublisherTopicSubscriber を使用して作成できます。分散トピックが複数の物理的トピックを表すという事実は、アプリケーションには全く意識されません。

注意: 恒久サブスクライバ (DurableTopicSubscriber) は、分散トピックに対しては作成できません。ただし、分散トピックのメンバーに対して恒久サブスクリプションを作成することはできます。こうすると、他のトピック メンバーは、恒久サブスクリプションを持つトピック メンバーにメッセージを転送します。

トピック メンバーはどこにでも配置できますが、単一の WebLogic Server、またはクラスタ内の任意の数のサーバによってサービスを受ける必要があります。分散トピックに送信されたメッセージは、分散トピック セット内のトピック メンバーすべてに送信されます。このため、分散トピックのすべてのサブスクライバは、分散トピック用にパブリッシュされたメッセージを受信できます。

送り先のトピック メンバーに直接パブリッシュされたメッセージ (つまりパブリッシャが送り先を指定しなかったメッセージ) も、その分散トピックのメンバーすべてに転送されます。これには、最初に分散トピックにサブスクライブしたサブスクライバと、その特定のトピック メンバーにたまたま割り当てられているサブスクライバが含まれます。つまり、特定の分散トピックのメンバーにメッセージをパブリッシュすると、それが分散トピックの他のメンバーすべてに自動的に転送されます。これは、分散トピックにメッセージをパブリッシュすると、その分散トピックのメンバーすべてにメッセージが自動的に転送されることと同じです。特定の分散送り先のメンバーのルックアップの詳細については、送り先メンバーへのアクセスを参照してください。

分散トピックへのメッセージ駆動型 Bean のデプロイ

MDB を分散トピックにデプロイし、JMS サーバ上の分散トピックの 2 つのメンバーをホストしているクラスタ内の WebLogic Server インスタンスを対象とした場合、MDB は分散トピックのいずれのメンバーにもデプロイされます。これは、MDB が分散トピックのメンバーの送り先名に固定されているからです。

したがって、WebLogic Server インスタンスにデプロイされている分散トピックのメンバー数に応じて、MDB ごとに [送信メッセージ数] * [分散トピックのメンバー数] のメッセージを受信することになります。たとえば、JMS サーバに 2 つの分散トピックのメンバーが含まれている場合、各メンバーに 1 つ、合わせて 2 つの MDB がデプロイされるので、2 倍の数のメッセージを受信することになります。

TopicPublisher

トピック パブリッシャを作成する際、提供されている送り先が分散送り先である場合、その送り先に送信されるメッセージはすべて次のように、分散トピックのアクセス可能なトピック メンバーすべてに送信されます。

TopicSubscriber

トピック サブスクライバを作成するとき、提供されているトピックが分散トピックの場合、トピック サブスクライバはその分散トピックにパブリッシュされたメッセージを受信します。

トピック サブスクライバが分散トピックのトピック メンバーの 1 つまたは複数にアクセスできない場合は、メッセージが永続的であるか非永続的であるかに応じて次の事態が発生します。

最終的に、トピック サブスクライバは物理的なトピック メンバーに固定されます。そのトピック メンバーにアクセスできなくなった場合は、次のようにトピック サブスクライバに JMSException が発行されます。

このような例外を受信した場合、アプリケーションはトピック サブスクライバを終了して再作成できます。分散トピック内のその他のトピック メンバーにアクセス可能な場合は、新しいトピック サブスクライバが作成され、これらのトピック メンバーのいずれかに固定されます。他のトピック メンバーにアクセスできない場合、トピック サブスクライバの再作成はできないため、後で作成を再試行する必要があります。

送り先メンバーへのアクセス

分散送り先内の分散メンバーにアクセスするには、コンフィグレーションされた JNDI 名を使用して分散メンバーをルックアップするか、JMS サーバ名と JMSQueueMBean または JMSTopicMBean コンフィグレーション MBean 名をフォワード スラッシュ (/) で区切って、createQueue() メソッドまたは createTopic() メソッドのどちらかに提供する必要があります。

たとえば、次のコードは、JMS サーバ (myServer) 上の分散キュー (myQueue) の特定のメンバーをルックアップする方法を示します。

queue = myQueueSession.createQueue("myServer/myQueue");

注意: createQueue() メソッドまたは createTopic() メソッドを呼び出す際、フォワード スラッシュ (/) を含む文字列は、送り先ではなく、分散送り先メンバーの名前であると見なされます。このような分散送り先メンバーが存在しない場合、呼び出しは InvalidDestinationException で失敗します。

分散送り先におけるメッセージのロード バランシング

WebLogic JMS は分散送り先を使用して、複数の物理的送り先にメッセージの負荷を分散し、バランスを取ることができます。これによって、リソースがさらに効率的に利用され、応答時間が改善されます。WebLogic JMS のロード バランシング アルゴリズムでは、メッセージの送信先となる物理的送り先に加えて、コンシューマの割り当て先の物理的送り先も決定されます。

分散送り先のロード バランシングのコンフィグレーションの詳細については、『管理者ガイド』の「メッセージのロード バランシングのコンフィグレーション」を参照してください。

ロード バランシング オプション

WebLogic JMS は、任意の送り先セットに含まれている複数の物理的送り先間でメッセージのロード バランシングを行うための 2 種類のアルゴリズムをサポートしています。これらのロード バランシング オプションのどちらかを選択するには、Adminstration Console で分散トピックまたは分散キューをコンフィグレーションします。

ラウンドロビン分散

ラウンドロビン アルゴリズムでは、WebLogic JMS は送り先内の物理的送り先の序列を管理します。メッセージの負荷は、WebLogic Server コンフィグレーション (config.xml) ファイルに定義されている順番で、一度に 1 つずつ物理的送り先に分散されます。各 WebLogic Server は、同一の序列を維持しますが、その序列内の位置は異なります。特定の分散送り先を使用して単一のサーバ内で複数のスレッドを実行すると、スレッドからメッセージが生成されるたびに、メンバーが割り当てられている物理的送り先に関連して、これらのスレッドが互いに影響し合うことになります。ラウンドロビンはデフォルトのアルゴリズムで、コンフィグレーションの必要はありません。

特定の分散送り先に対し、セット内の物理的送り先のいずれかに重みが割り当てられている場合、それらの物理的送り先は序列内に複数回発生します。たとえば、送り先 A、B、および C の重みがそれぞれ 2、5、および 3 である場合、序列は A、B、C、A、B、C、B、C、B、B となります。つまり、いくつものパスが基本的な序列 (A、B、C) 内に組み込まれます。パスの数は、セット内の送り先の最大の重みと等しくなります。それぞれのパスでは、パスの序数値以上の重みを持つ送り先のみが序列に含められます。このロジックに従うと、ここに挙げた例では次の結果が生じます。

ランダム分散

ランダム分散アルゴリズムでは、物理的送り先に割り当てられている重みを使用して、一連の物理的送り先の重み付き送り先を計算します。メッセージの負荷は、疑似ランダム的に送り先にアクセスすることで、物理的送り先に分散されます。短期的には、負荷は重みには直接比例しません。長期的には、極限に近い分散が行われます。純粋なランダム分散は、重みすべてに同じ値を設定することで達成できます。この値は通常 1 です。

メンバーが追加または除去された (管理者が行うか、WebLogic Server がシャットダウンまたは再起動した結果発生したもの) 場合は、分散を再計算する必要があります。ただし、このようなイベントは頻繁に発生せず、計算は通常単純で、O(n) 時間で実行されます。

コンシューマのロード バランシング

アプリケーションがコンシューマを作成するときは、送り先を提供する必要があります。その送り先が分散送り先を表す場合、WebLogic JMS ではコンシューマのメッセージ受信元となる物理的送り先を見つける必要があります。どの送り先メンバーを使用するかは、ロード バランシング オプションに説明されているロード バランシング アルゴリズムのいずれかを用いて選択します。選択は一度だけ、つまりコンシューマが作成されたときに行います。その後、コンシューマはそのメンバーのみからメッセージを受信するようになります。

プロデューサのロード バランシング

プロデューサがメッセージを送信するとき、WebLogic JMS はメッセージが送信される送り先を確認します。送り先が分散送り先である場合は、メッセージの送信先が WebLogic JMS によって決定されます。つまり、プロデューサはロード バランシング オプションで説明されているロード バランシング アルゴリズムのいずれかに従って、送り先のメンバーのいずれかに送信します。

プロデューサはメッセージを送信するたびにこのような決定を行います。ただし、コンシューマとプロデューサ間の序列の保証が脅かされることはありません。コンシューマのロード バランシングがいったん行われると、コンシューマは単一の送り先メンバーに固定されるためです。

注意: プロデューサが永続メッセージを分散送り先に送信しようとした場合、永続ストレージを利用している分散メンバーにまずメッセージが転送されるよう、あらゆる努力をします。ただし、分散メンバーがいずれも永続ストレージを利用していない場合でも、メッセージは選択されているロードバランシング アルゴリズムに従って、メンバーのいずれかに送信されます。

ロード バランシングのヒューリスティック

ロード バランシング オプションに説明されているアルゴリズムに加えて、WebLogic JMS では送り先のインスタンスを選択するときに次のヒューリスティックが使用されます。

トランザクション アフィニティ

トランザクション セッション内で複数のメッセージを作成するときは、作成されたメッセージすべてを同じ WebLogic Server に送信しようとします。つまり、セッションが単一の分散送り先に複数のメッセージを送信した場合は、すべてのメッセージが同じ物理的送り先に転送されます。セッションによって複数のメッセージが複数の異なる分散送り先に送信された場合は、同じ WebLogic Server がサービスを提供する一連の物理的送り先が選択されるようになります。

サーバ アフィニティ

WebLogic Server が分散送り先セット内の物理的送り先の間でコンシューマまたはプロデューサのロード バランシングを試みるときは、同じ WebLogic Server で実行されている物理的送り先の間でのロード バランシングがまず行われます。

注意: 分散送り先に対するサーバ アフィニティのコンフィグレーションの詳細については、『管理者ガイド』の「サーバ アフィニティのコンフィグレーション」を参照してください。

コンシューマのないキュー

複数のリモートの物理的キュー間でコンシューマのロード バランシングを行う場合、1 つまたは複数のキューにコンシューマがないとき、それらのキューだけがロード バランシングの対象となります。セット内の物理的キューすべてに少なくとも 1 つのコンシューマが含まれるようになると、標準のアルゴリズムが適用されます。

また、プロデューサがメッセージを送信するとき、コンシューマのないキューはメッセージ作成の対象にはなりません。ただし、任意のキューのインスタンスのいずれにもコンシューマが含まれていない場合を除きます。

ロード バランシングの回避

アプリケーションは、個別の物理的送り先に直接アクセスすることで、ロード バランシングを回避できます。つまり、物理的送り先に JNDI 名がない場合でも、createQueue() メソッドまたは createTopic() メソッドを使用して参照することができます。

JNDI ルックアップ

物理的送り先に JNDI 名がある場合は、JNDI を使用してルックアップできます。それによって返された送り先を使用すると、コンシューマまたはレシーバを作成できます。

CreateQueue() および CreateTopic()

アプリケーションでは、createQueue() メソッドや createTopic() メソッドを使用してトピックまたはキューの参照を取得することもできます。これらのメソッドを使用するときは、参照先の送り先を識別するベンダ固有の文字列を提供する必要があります。WebLogic JMS 用のベンダ固有の文字列は、server/destination の形式になっています。ここで、「server」は JMS サーバ名で、「destination」はその JMS サーバ上のキューまたはトピックの名前を表します。

接続ファクトリ

アプリケーションにおいて、分散送り先を使用して、複数の物理的送り先間でプロデューサやコンシューマを分散、つまりバランスさせることは行っても、メッセージが作成されるたびにロード バランシングの決定を行いたくない場合は、[ロード バランスを有効化] 属性を無効 (False に設定) にした状態で、接続ファクトリを使用します。

分散送り先のロード バランシングのコンフィグレーションの詳細については、『管理者ガイド』の「メッセージのロード バランシングのコンフィグレーション」を参照してください。

分散送り先の移行

WebLogic Server 7.0 サービス移行機能を利用する JMS の実装では、JMS サーバに障害が発生した場合、クラスタ内の別の WebLogic Server に、分散送り先のメンバーとともにサーバを移行できます。ただし、移行先の WebLogic Server は物理的送り先すべてを持つ JMS サーバを既にホストしている可能性があります。このような場合は、同じ WebLogic Server が単一の送り先に対して 2 つの物理的送り先をホストするような状況が生じます。WebLogic Server はその送り先に対して複数の物理的送り先をホストできるため、これは短期的には許容できますが、このような状況でのロード バランシングは効果が半減します。

このような状況では、移行先の WebLogic Server 上の JMS サーバは独立して動作します。これは、2 つの送り先インスタンスの結合や、1 つのインスタンスの無効化を避けるためです。このようなことが発生すると、メッセージが長時間使用できなくなる場合があります。ただし、長期的な目的は、移行された JMS サーバをクラスタ内のさらに別の WebLogic Serverに最終的に再移行することにあります。

JMS 移行可能先のコンフィグレーションの詳細については、JMS 移行可能対象のコンフィグレーションを参照してください。

分散送り先のフェイルオーバ

サーバに障害が発生したために JMS サーバが別の WebLogic Server に移行したときは、障害の発生した送り先メンバーに固定されているコンシューマを終了し、再作成する必要があります。

WebLogic Server の障害の回復手順の詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

 

Back to Top Previous Next