ナビゲーションをスキップ

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

  前 次 前/次ボタンと目次ボタンとの区切り線 目次  

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

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

注意 : この節で説明する JMS クラスの詳細については、Sun Microsystems の Java Web サイトにある「JMS の Javadoc」を参照してください。

 


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

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

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

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


 

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

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

 


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

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

表 4-1 WebLogic JMS パッケージ 

パッケージ名

説明

javax.jms

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

javax.naming

weblogic.jndi

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

javax.transaction.UserTransaction

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

weblogic.jms.ServerSessionPoolFactory

WebLogic Server 8.1 では非推奨になっている。
ServerSessionPoolFactory クラスは webLogic.jms.extensions パッケージで使用できる。「weblogic.jms.extensions.ServerSessionPoolFactory」を参照。

weblogic.jms.extensions

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

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

import javax.jms.*;
import javax.naming.*;
import javax.transaction.*;

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

import weblogic.jms.extensions.ServerSessionPoolFactory;

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

import weblogic.jms.extensions.*;

 


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

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

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

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


 

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

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

これらの節に記述されている JMS クラスとメソッドの詳細については、「WebLogic JMS のクラス」、「javax.jms」、または weblogic.jms.extensions の Javadoc を参照してください。

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

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

接続ファクトリをルックアップするには、あらかじめ接続ファクトリをコンフィグレーション情報の一部として定義しておく必要があります。WebLogic JMS には、コンフィグレーションの一部として組み込まれているデフォルト接続ファクトリが 2 つ用意されています。このファクトリは、JNDI 名 weblogic.jms.ConnectionFactoryweblogic.jms.XAConnectionFactory でルックアップできます (これらは JTA トランザクションを有効化します)。管理者はコンフィグレーション時に新しい接続ファクトリをコンフィグレーションできますが、これらのファクトリにはユニークな名前を付ける必要があります。そうしないとサーバが起動しません。接続ファクトリのコンフィグレーションおよび利用可能なデフォルト値の詳細については、Administration Console オンライン ヘルプの「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-6 で説明した非トランザクション セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション セッションの場合、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 型の引数と、表 2-6 非トランザクション セッションで使用する確認応答モードで説明した非トランザクション セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション セッションの場合、acknowledgeMode 属性は無視されます。この場合、メッセージは commit() メソッドでトランザクションがコミットされたときに確認応答されます。

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

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

送り先をルックアップする場合、事前に WebLogic JMS システム管理者によって送り先がコンフィグレーションされている必要があります。送り先のコンフィグレーションについては、Administration Console オンライン ヘルプの「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 名を指定します。

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」、「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() メソッドでは、「./Destination_Name」構文を使用して、送り先をルックアップする場合のサーバ アフィニティを示すこともできます。これにより、JMS 接続の接続ファクトリ ホストと同じ JVM にローカルにデプロイされた送り先の位置が指定されます。名前がローカル JVM にない場合は、同じ名前が別の JVM にデプロイされていても例外が送出されます。

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

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

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

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

MessageProducer クラスと MessageConsumer クラスの詳細については、「MessageProducer オブジェクトと MessageConsumer オブジェクト」、または、それぞれ「javax.jms.MessageProducer」、「javax.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 と「weblogic.jms.extensions.WLSession」Javadoc を参照してください。Message クラスとそのメソッドの詳細については、「Message オブジェクト」または「javax.jms.Message」の Javadoc を参照してください。

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

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

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

  1. onMessage() メソッドを持つ javax.jms.MessageListener インタフェースを実装します。
  2. 注意 : onMessage() メソッドのインタフェースの例については、「例 : PTP アプリケーションの設定」を参照してください。

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

  3. 次の MessageConsumer メソッドを使用してメッセージ リスナを設定し、リスナ情報を引数として渡します。
  4. public void setMessageListener(
    MessageListener listener
    ) throws JMSException
  5. 必要に応じて、「セッション例外リスナの定義」で説明するように、例外を取得するためのセッションの例外リスナを実装します。

メッセージ リスナの設定を解除するには、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() メソッドを使用します。

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

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

次の例は、WL_HOME\samples\server\examples\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);
}

注意 : EJB またはサーブレットの 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 のクラス」または「javax.jms」の Javadoc を参照してください。

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

次の例は、WL_HOME\samples\server\examples\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() メソッドに渡されます。TopicReceive の例の onMessage() インタフェースは、QueueReceive onMessage() インタフェース (「例 : PTP アプリケーションの設定」を参照) と同じです。

この例で使用されている JMS クラスの詳細については、「WebLogic JMS のクラス」または「javax.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 オブジェクト」または「javax.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 では、以下に示す独自の属性も提供されています (「メッセージ プロデューサ属性の設定」を参照)。

配信モードを PERSISTENT として定義した場合、Administration Console オンライン ヘルプの「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 では、以下に示す独自の属性も提供されています (「メッセージ プロデューサ属性の設定」を参照)。

配信モードを PERSISTENT として定義した場合、Administration Console オンライン ヘルプの「JMS : コンフィグレーション」で説明しているように、バッキング ストアをコンフィグレーションする必要があります。

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

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

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

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

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

メッセージ プロデューサ属性の設定

前節で説明したように、メッセージを送信するときには、配信モード、優先度、および存続時間をオプションで指定できます。指定しない場合、これらの属性は接続ファクトリのコンフィグレーション属性 (Administration Console オンライン ヘルプの「JMS : コンフィグレーション」を参照) に設定されます。

代わりに、メッセージ プロデューサの set メソッドを使用して、配信モード、優先度、配信時間、存続時間、再配信遅延 (タイムアウト)、および再配信制限の各属性値を動的に設定できます。次の表に、メッセージ プロデューサの set メソッドと get メソッドを、動的コンフィグレーション可能な属性ごとに示します。

注意 : 配信モード、優先度、存続時間、配信時間、再配信遅延 (タイムアウト)、および再配信制限の各属性値は、[配信モードのオーバーライド]、[優先順位のオーバーライド]、[生存時間のオーバーライド]、[配信時間のオーバーライド]、[再配信遅延のオーバーライド]、および [再配信の制限] の各コンフィグレーション属性を使用して送り先によってオーバーライドできます。詳細については、Administration Console オンライン ヘルプの「JMS キューおよびトピック送り先のタスク」を参照してください。

表 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

再配信の制限

public void setRedeliveryLimit(
int redeliveryLimit
) throws JMSException

public int getredeliveryLimit(
) throws JMSException

送信タイムアウト

public void setsendTimeout(
long sendTimeout
) throws JMSException

public long getsendTimeout(
) throws JMSException

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

MessageProducer クラスのメソッドの詳細については、Sun の「javax.jms.MessageProducer」の Javadoc または「weblogic.jms.extensions.WLMessageProducer」の Javadoc を参照してください。

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

次の例は、WL_HOME\samples\server\examples\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\examples\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 : 非同期メッセージ リスナを登録する (メッセージ コンシューマ) (オプション)」を参照してください。

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

非同期メッセージ パイプライン

メッセージの生成速度が非同期メッセージ リスナ (コンシューマ) によるそれらの消費速度を上回る場合、JMS サーバは複数の未消費メッセージをまとめ、別の使用可能な非同期メッセージ リスナのセッションに送ります。こうした処理中のメッセージはメッセージ パイプラインと呼ばれ、JMS ベンダによってはメッセージ バックログとも呼ばれます。パイプラインまたはバックログのサイズは、非同期コンシューマで蓄積され、メッセージ リスナに渡されていないメッセージの数です。

メッセージ パイプラインのコンフィグレーション

クライアントの最大パイプライン サイズを設定するには、クライアントの接続ファクトリの [最大メッセージ数] 属性をコンフィグレーションします。この属性は、非同期コンシューマに存在し、メッセージ リスナにまだ渡されていないメッセージの最大数です。デフォルト値は 10 です。

JMS 接続ファクトリのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「JMS 接続ファクトリのタスク」を参照してください。

パイプライン メッセージの動作

コンフィグレーションされたメッセージ パイプラインは、次のように動作します。

注意 : 接続ファクトリの [最大メッセージ数] パイプライン サイズは、JMS サーバおよび送り先の最大メッセージ割り当ての設定とは関係ありません。

パイプライン メッセージは、ネットワーク転送で単一のメッセージに集約される場合があります。パイプライン メッセージのサイズが大きい場合、書き込まれるデータの集約サイズが最大転送値を超え、望ましくない動作が発生する場合があります。たとえば、t3 プロトコルでは、デフォルトの最大メッセージ サイズは 10MB に設定されており、サーバの MaxT3MessageSize 属性でコンフィグレーションできます。このため、10 通の 2MB メッセージがパイプライン処理される場合、t3 の制限を上回る場合があります。

メッセージの同期受信

メッセージを同期的に受信するには、以下の 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\examples\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\examples\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-6 で説明したように、確認応答モードが CLIENT_ACKNOWLEDGE に設定されている非トランザクション セッションだけに適用されます。同期受信される AUTO_ACKNOWLEDGE メッセージは確認応答済みのため、回復されないことがあります。

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

public void recover(
) throws JMSException

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

注意 : キュー内のメッセージは、必ずしも元の配信順序と同じ順序で、または同じキュー コンシューマに再配信されるとは限りません。再配信メッセージの正しい配信順序の保証については、「メッセージの再配信の順序付け」を参照してください。

 


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

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

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

public void acknowledge(
) throws JMSException

acknowledge() メソッドは、接続ファクトリの [確認応答ポリシー] 属性のコンフィグレーションによって次のように異なります。

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

 


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

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

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

public void close(
) throws JMSException

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

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

次の例は、WL_HOME\samples\server\examples\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 固有の拡張を使用して接続ファクトリ設定をオーバーライドできます。セッション属性は動的なので、いつでも変更できます。セッションの再配信遅延を変更すると、メッセージが非恒久トピックを使用したセッション内のものでない限り、変更後にそのセッションで消費およびロールバック (または回復) されるすべてのメッセージに影響します。

注意 : セッションが非恒久トピックを使用している場合、setRedeliveryDelay メソッドは適用されません。これにより、非恒久トピック コンシューマを使用してワークフローを駆動している場合に、予想外の動作が生じることがあります。

セッションに対して再配信遅延を設定するメソッドは、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 によるアプリケーションへのメッセージ再配信の試行回数に対して制限を設けることで、システム リソースをより効率的に管理できます。配信できなかったメッセージを、指定したローカル JMS サーバ上のエラー送り先に後で再配信するかどうかを定義することもできます。再配信の制限がコンフィグレーションされていて、エラー送り先がコンフィグレーションされていない場合、永続メッセージまたは非永続メッセージは再配信の制限に達すると削除され、例外は送出されません。

注意 : この、再配信の制限をコンフィグレーションしてエラー送り先の動作を指定しない場合の影響は、トランザクション メッセージに関しても当てはまります。この場合トランザクション メッセージは後の再配信でロールバックされず、例外も送出されません。

代わりに、メッセージ プロデューサの set メソッドを使用して、再配信の制限値を動的に設定できます (「メッセージ プロデューサ属性の設定」を参照)。

送り先のメッセージ再配信制限をコンフィグレーションする

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

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

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

JMS サーバにエラー送り先 (exampleQueueError など) をコンフィグレーションしておくと、既存の送り先では、Administration Console の [コンフィグレーション|再配信] タブにある [エラー送り先] 属性を使用して、エラー送り先を選択できます。詳細については、Administration Console オンライン ヘルプの「JMS キューおよびトピック送り先のタスク」を参照してください。

メッセージの再配信の順序付け

JMS 仕様により、特定のプロデューサからコンシューマに最初に配信されるすべてのメッセージは、生成された順序でコンシューマに到着することが保証されています。WebLogic JMS はこの要件を満たすだけでなく、さらに「メッセージの再配信の順序付け」機能を提供しています。この機能は、再配信メッセージについても正しい順序を保証します。

この保証を提供するために、WebLogic JMS では特定の制約を課す必要があります。制約は次のとおりです。

非同期コンシューマ (メッセージング ブリッジおよび MDB を含む) に必要な接続ファクトリのコンフィグレーション

WebLogic メッセージング ブリッジまたは MDB を使用する JMS アプリケーションを含む非同期コンシューマについて、順序付き再配信を発生させるには、メッセージ パイプラインのサイズを 1 に設定する必要があります。メッセージ パイプラインのサイズは、受信側アプリケーションが使用する JMS 接続ファクトリの [最大メッセージ数] 属性を使用して設定します。1 より大きい値は、再配信メッセージの前に追加の送信中メッセージがある可能性を示します。MDB アプリケーションでは、アプリケーションに固有の JMS 接続ファクトリを定義し、その接続ファクトリの [最大メッセージ数] 属性の値を 1 に設定する必要があります。さらに、MDB アプリケーションの EJB 記述子で接続ファクトリを参照する必要があります。

JMS 接続ファクトリのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「JMS 接続ファクトリのタスク」を参照してください。

メッセージング ブリッジのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「メッセージング ブリッジ」を参照してください。

EJB のプログラミングの詳細については、『WebLogic エンタープライズ JavaBeans (EJB) プログラマーズ ガイド』の「メッセージ駆動型 EJB」を参照してください。

パフォーマンスの制限

順序付き再配信機能を実装した JMS アプリケーションには、JTA トランザクション (具体的には MDB および WebLogic メッセージング ブリッジ) を使用する非同期コンシューマのパフォーマンス低下が伴います。原因は送信中メッセージ数が強制的に 1 に削減されることであり、そのためメッセージは集約されずにクライアントに送信されます。

期限切れメッセージの処理

WebLogic JMS には、アクティブなメッセージ有効期限ポリシーが用意されています。このポリシーでは、期限切れメッセージの検索方法と処理方法を設定できます。この機能では、単純に期限切れメッセージを破棄するか、期限切れメッセージを破棄してそれをログに記録するか、または期限切れメッセージをローカル JMS サーバのエラー送り先に転送することによって期限切れメッセージが即座に消去できます。

メッセージ有効期限ポリシーのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「期限切れメッセージの処理」を参照してください。

 


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

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

メッセージが送信されるのは 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 を参照してください。

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

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

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

注意 : メッセージの配信時間の値を設定しても、このフィールドには影響しません。これは、メッセージが送信またはパブリッシュされるたびに、JMS がこの値をプロデューサの値でオーバーライドするためです。ここで説明するメッセージ配信時間の方法は、プロデューサによって設定される他の JMS メッセージ フィールド (配信モード、優先度、配信時間、存続時間、再配信遅延、再配信制限など) と似ています。特に、これらのフィールドの設定は JMS プロバイダ (WebLogic 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 属性を設定できます。

存続時間の値との関係

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

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

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

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

スケジューリング済み TimeToDeliverOverrideweblogic.jms.extensions.Schedule クラスを使用しても指定できます。このクラスでは、スケジュールを取得し、次回のメッセージ配信時間を返すメソッドが提供されています。

説明

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 時

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 です。

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 {

 


接続の管理

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

接続例外リスナの定義

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

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

接続に対する例外リスナを定義するには、次の 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 接続ファクトリのタスク」を参照してください。

 


送り先の動的作成

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

 


送り先の動的削除

次のいずれかの方法を使用して、JMS 送り先 (キューまたはトピック) を動的に削除できます。

JMS サーバは削除された送り先をリアル タイムに削除します。従って、削除を有効にするために JMS サーバを再デプロイする必要はありません。送り先の動的削除に関する手順については、以降の節で説明します。

送り先を削除するための事前条件

送り先の削除を正常に完了するには、次の事前条件が満たされている必要があります。

これらの事前条件のいずれかが満たされていない場合、削除は実行できません。

送り先が削除されている場合

送り先を削除する場合、以下の動作とセマンティクスが適用されます。

削除された送り先のトラブルシューティングに使用するメッセージのタイムスタンプ

永続メッセージがある送り先が、削除されてからすぐに再作成され、そのとき JMS サーバが動作中でなかった場合、JMS サーバは送り先のバージョン番号 (コンフィグレーション ファイル config.xmlCreationTime フィールドを使用) と永続メッセージ内の送り先バージョン番号を比較します。この場合、古い送り先に残っている永続メッセージのバージョン番号は、config.xml ファイルにある再作成された送り先のバージョン番号よりも古い番号になります。JMS サーバが再起動すると、残っている永続メッセージは破棄されます。

ただし、永続メッセージのバージョン番号が、再作成された送り先の config.xml にあるバージョン番号よりも新しい場合は、送り先が削除されてから (JMS サーバが動作中でない状態で) 再作成されたときにシステム クロックがロールバックされたか、異なる config.xml が使用されています。この場合、JMS サーバの起動が失敗します。永続メッセージを保存するために、永続メッセージ内のバージョン番号に一致するバージョン番号 (CreationTime フィールド) を config.xml に設定できます。または、config.xml のバージョン番号を、永続メッセージ内のバージョン番号よりも新しい番号に変更できます。このようにすると、JMS サーバは再起動時にメッセージを削除できます。

削除した送り先の統計

削除した送り先およびホストする JMS サーバに関する統計は、メッセージが物理的に削除されたときに更新されます。ただし、別の処理の結果が出るまで削除が遅れるメッセージもあります。このようなメッセージには、トランザクションで送受信されるメッセージや、クライアントが受信する確認応答されていない非トランザクション メッセージが含まれます。

 


一時的な送り先の使い方

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

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

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

永続ストアの定義

メッセージがサブスクライバに配信されるか、または期限切れになるまで WebLogic JMS がそのメッセージを保持できるようにするためには、永続ファイルまたはデータベース ストアをコンフィグレーションして JMS サーバに割り当てる必要があります。

JMS ストアのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「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 になっています。

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

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

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

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

public void unsubscribe(
String name
) throws JMSException

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

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

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

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

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

  1. 必要に応じて、「恒久サブスクリプションの削除」の手順に従って恒久サブスクリプションを削除します。
  2. この手順は省略可能です。この手順が明示的に実行されない場合は、次の手順で恒久サブスクリプションが再作成されるときに暗黙的に削除が行われます。

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

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

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

Administration Console を使用して恒久サブスクリプションをモニタおよび削除することができます。詳細については、Administration Console オンライン ヘルプの「JMS : コンフィグレーション」を参照してください。

 


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

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

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

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

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

JMSDestination1

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

JMSRedeliveryLimit1

public void setJMSRedeliveryLimit(
int redelivered
) throws JMSException

public int getJMSRedeliveryLimit(
) 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


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

WL_HOME\samples\server\examples\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-3 メッセージ プロパティのデータ型ごとの 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-4 メッセージ プロパティの変換表 

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

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

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);

メッセージ プロパティ フィールドの詳細については、「メッセージ プロパティ フィールド」または「javax.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\examples\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 で入手できます。

注意 : XML メッセージの構文には十分注意してください。不正な XML メッセージ (終了タグの欠落など) はどの XML セレクタとも一致しません。

以下の環境では、メソッドは 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 確認応答モードを使用しているアプリケーションには効果がありません。このようなアプリケーションは、メッセージの選択がサーバサイドではなくクライアントサイドで行われるため、拡張の必要性はありません。

 


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

注意 : セッション プールは現在ほとんど使用されていません。理由は、J2EE 仕様の必須の部分ではないこと、JTA ユーザ トランザクションをサポートしていないこと、そして大部分がメッセージ駆動型 Bean (MDB) に取って代わられたことです。MDB の方が簡単で管理しやすく、高機能です。MDB の設計の詳細については、『WebLogic エンタープライズ JavaBeans (EJB) プログラマーズ ガイド』の「メッセージ駆動型 EJB」を参照してください。

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

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

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

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

サーバ セッション プール機能


 

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

  1. サーバ セッション プールからサーバ セッションを取得する
  2. サーバ セッションのセッションを取得する
  3. セッションに 1 つまたは複数のメッセージをロードする
  4. サーバ セッションを開始して、メッセージを受信する
  5. メッセージの処理が終了したら、サーバ セッションを解放してプールに戻す

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

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

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


 


 

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

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

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

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

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

WebLogic JMS では、デフォルトで次のような ServerSessionPoolFactory オブジェクトが定義されています。weblogic.jms.extensions.ServerSessionPoolFactory:<name>。ここで <name> には、セッション プールの作成先になる JMS サーバの名前を指定します。

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

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

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

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

サーバ セッション プール ファクトリの詳細については、「ServerSessionPoolFactory オブジェクト」または「weblogic.jms.extensions.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.extensions.ServerSessionPoolFactory」の Javadoc を参照してください。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.extensions.ServerSessionPoolFactory」の Javadoc を参照してください。ConnectionConsumer クラスの詳細については、「javax.jms.ConnectionConsumer」の Javadoc を参照してください。

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

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

ConnectionConsumer クラスの詳細については、「ConnectionConsumer オブジェクト」または「javax.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 には、トピック用の ConnectionConsumers を作成する、以下の 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.extensions.ServerSessionPoolFactory

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

private final static String SESSION_POOL_FACTORY=
"weblogic.jms.extensions.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.extensions.ServerSessionPoolFactory

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

private final static String SESSION_POOL_FACTORY=
"weblogic.jms.extensions.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 メッセージング モデル、および非恒久サブスクライバのみでサポートされています。

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

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

手順 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-5 メッセージ プロデューサの 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 の例

マルチキャスト TTL の例


 

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

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

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

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

 


分散送り先の使用

分散送り先は、単一の JNDI 名でアクセスし、クライアントからは単一の論理的な送り先に見える一連の物理的な JMS 送り先 (キューまたはトピック) です。分散送り先のメンバーは、実際にはクラスタ内の複数のサーバに分散されており、各送り先メンバーは個々の JMS サーバに属しています。

複数の物理的キューおよびトピックを単一の分散送り先のメンバーとしてコンフィグレーションできるようにすることで、WebLogic JMS はクラスタ内の物理的な送り先の高可用性とロードバランシングを実現します。一度適切にコンフィグレーションすると、プロデューサとコンシューマがその分散送り先に対してメッセージを送受信できるようになります。WebLogic JMS は、分散送り先のすべてのメンバー間でメッセージングの負荷を分散します。サーバの障害で送り先メンバーがアクセスできなくなった場合、トラフィックはセット内の他のアクセス可能な送り先メンバーにリダイレクトされます。

コンフィグレーション プロセスを効率化するために、Administration Console には次のような分散送り先を簡単にコンフィグレーションするための「自動デプロイ」機能が用意されています。

Administration Console を使用して分散送り先をコンフィグレーションする手順については、Administration Console オンライン ヘルプの「JMS 分散送り先のタスク」を参照してください。

以下の節では、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 のロード バランシング アルゴリズムでは、メッセージの送信先となる物理的送り先に加えて、コンシューマの割り当て先の物理的送り先も決定されます。

分散送り先に対するロード バランシングのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「分散送り先におけるメッセージのロード バランシングのコンフィグレーション」を参照してください。

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

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 インスタンスで実行されているすべてのローカル メンバーの間でのロード バランシングがまず行われます。

JMS 接続ファクトリの [サーバ アフィニティを有効化] オプションを使用して分散送り先に対するサーバ アフィニティをコンフィグレーションする方法については、Administration Console オンライン ヘルプの「分散送り先のサーバ アフィニティのコンフィグレーション」を参照してください。

注意 : [サーバ アフィニティを有効化] 属性は、キュー ブラウザには影響しません。したがって、分散キューに作成されたキュー ブラウザは、サーバ アフィニティが有効になっていてもリモート分散キュー メンバーに固定できます。

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

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

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

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

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

JNDI ルックアップ

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

CreateQueue() および CreateTopic()

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

接続ファクトリ

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

分散送り先に対するロード バランシングのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「分散送り先におけるメッセージのロード バランシングのコンフィグレーション」を参照してください。

[サーバ アフィニティを有効化] 属性を使用した場合の分散送り先ロード バランシングへの影響

次の表では、JMS 接続ファクトリの [サーバ アフィニティを有効化] 属性の設定が、分散送り先メンバーのロード バランシングの優先権に与える影響について説明します。優先順位は、操作のタイプ、および恒久サブスクリプションまたは永続メッセージが含まれているかどうかによって異なります。

分散送り先の [サーバ アフィニティを有効化] 属性は、ClusterMBean の [デフォルトのロード バランス アルゴリズム] 属性によって提供されるサーバ アフィニティとは異なります。後者は、JMS 接続ファクトリでクライアント接続用の初期コンテキスト アフィニティを作成するためにも使用されます。詳細については、『WebLogic Server クラスタ ユーザーズ ガイド』の「EJB と RMI オブジェクトのロード バランシング」および「クライアント接続の初期コンテキスト アフィニティとサーバ アフィニティ」を参照してください。

表 4-6 サーバ アフィニティのロード バランシングの優先権


操作

[サーバ アフィニティを
有効化]


ロード バランシングの優先権

  • キューの createReceiver()

  • トピックの createSubscriber()

True

    1. コンシューマを持たないローカル メンバー

    2. ローカル メンバー

    3. コンシューマを持たないリモート メンバー

    4. リモート メンバー

キューの createReceiver()

False

    1. コンシューマを持たないメンバー

    2. メンバー

トピックの createSubscriber()
(注意 : 非恒久サブスクライバ)

True または False

    1. コンシューマを持たないローカル メンバー

    2. ローカル メンバー

    3. ローカル プロキシ トピック (Administration Console オンライン ヘルプの「分散送り先システム サブスクリプションおよび代理トピック メンバーのモニタ」を参照)

  • キューの createSender()

  • トピックの createPublisher()

True または False

JMS プロデューサ作成のロード バランシング用の独立した機能は存在しない。JMS プロデューサは、JMS 接続のロード バランシングまたは固定が行われるサーバで作成される。

接続ファクトリを介して作成した JMS 接続のロード バランシングの詳細については、『WebLogic Server クラスタ ユーザーズ ガイド』の「EJB と RMI オブジェクトのロード バランシング」および「クライアント接続の初期コンテキスト アフィニティとサーバ アフィニティ」を参照。

QueueSender.send() を使用する永続メッセージ

True

    1. コンシューマとストアを持つローカル メンバー

    2. コンシューマとストアを持つリモート メンバー

    3. ストアを持つローカル メンバー

    4. ストアを持つリモート メンバー

    5. コンシューマを持つローカル メンバー

    6. コンシューマを持つリモート メンバー

    7. ローカル メンバー

    8. リモート メンバー

QueueSender.send() を使用する永続メッセージ

False

    1. コンシューマとストアを持つメンバー

    2. ストアを持つメンバー

    3. コンシューマを持つメンバー

    4. メンバー

QueueSender.send() を使用する非永続メッセージ

True

    1. コンシューマを持つローカル メンバー

    2. コンシューマを持つリモート メンバー

    3. ローカル メンバー

    4. リモート メンバー

非永続メッセージ

  • QueueSender.send()

  • TopicPublish.publish()

False

    1. コンシューマを持つメンバー

    2. メンバー

セッション プール キューおよびトピックの createConnectionConsumer()

True または False

    1. ローカル メンバーのみ

注意 : セッション プールは現在ほとんど使用されていない。理由は、J2EE 仕様の必須の部分ではないこと、JTA ユーザ トランザクションをサポートしていないこと、そして大部分がメッセージ駆動型 Bean (MDB) に取って代わられたことである。MDB の方が簡単で管理しやすく、高機能である。

分散送り先の移行

サービス移行機能を利用するクラスタ化された JMS 実装では、JMS サーバとその分散送り先メンバーを、クラスタ内の別の WebLogic Server インスタンスに手動で移行できます。サービスの移行は、定期的なシステム保守の際や、クラスタ内のサーバに障害が発生した際に実施できます。

ただし、移行先の WebLogic Server に物理的送り先すべてを持つ JMS サーバがすでにホストされている場合もあります。そのような場合には、同じ WebLogic Server インスタンスが単一の分散送り先について 2 つの物理的送り先をホストするような状況が生じます。WebLogic Server インスタンスはその分散送り先に対して複数の物理的送り先をホストできるため、これは短期的には許容できますが、このような状況でのロード バランシングは効果が半減します。

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

JMS の移行可能な対象のコンフィグレーションについては、「JMS サーバの移行可能対象のコンフィグレーション」を参照してください。

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

JMS プロデューサおよび JMS コンシューマの JMS 接続をホストしているサーバ インスタンスに障害が発生した場合、これらの接続を使用しているすべてのプロデューサとコンシューマが閉じられ、クラスタ内の別のサーバ インスタンスでは再作成されません。また、JMS 送り先をホストしているサーバ インスタンスに障害が発生した場合、その送り先のすべての JMS コンシューマが閉じられ、クラスタ内の別のサーバ インスタンスでは再作成されません。

キュー プロデューサが作成された分散キュー メンバーに障害が発生したが、プロデューサの JMS 接続が存在する WebLogic Server がまだ実行されている場合、プロデューサは閉じられず、WebLogic JMS はロード バランシング オプションが有効になっているかどうかに関係なく別の分散キュー メンバーにフェイルオーバします。

WebLogic Server の障害から回復するための手順については、「WebLogic Server の障害からの回復」を参照してください。

 

フッタのナビゲーションのスキップ  ページの先頭 前 次