高度なメッセージング

このセクションでは、JMSのさまざまな高度なトピックについて説明します。 このガイドの他の箇所と比べると、このセクションの各トピックは関連性が薄いため、どこからでも読むことができます。 ここで説明されているトピックは通常、経験あるユーザが特別な状況でのみ使用するものであるため、JMSに精通していない場合はこのセクションを飛ばして、後からこれらの概念が必要になった場合に参照してください。

一時宛先

JMSでは、一時宛先と呼ばれる機能がサポートされています。これは、一時キューおよびトピックを動的に作成する場合に使用できます。 このような宛先は、管理者が作成するのではなく、通常、非持続メッセージの交換のための一時的なものです。 一時宛先にはそれぞれシステムにより生成される固有の名前があり、作成された接続範囲内でのみ使用できます。

JMSは一時宛先を使用して、Pub/SubまたはP2PメッセージングモデルでRPCのようなメカニズムを実装します。 この技術はリクエスタと呼ばれ、メッセージをパラメータとして受け取り、応答メッセージを返すrequestメソッドをサポートします。 リクエスタには、QueueRequestorTopicRequestorがあります。 背後で、requestメソッドにより次の手順が実行されます。

  1. 一時宛先が作成され、この宛先に提供されるメッセージヘッダのReplyToフィールドが設定されます。
  2. 次に、メソッドに提供されたメッセージが、メッセージの宛先に送信されます。
  3. 最後に、リクエスタが一時宛先への応答を待ちます。 応答が呼び出し側に返されます。

次の図に、リクエスタの動作を示します。

ユーザがリクエスタを使用するのは、リモートサービスのRPCスタイルを呼び出す場合です。 コンシューマが宛先からメッセージを受信すると、このメッセージが処理され、一時宛先に返されます。 JMSで提供されているリクエスタは、非常に単純なので、アプリケーション開発者は、タイムアウトのサポートなどより洗練されたリクエスタを実装することもあります。

メッセージ配信の停止

JMSには、接続内のコンシューマへのメッセージ配信を開始および停止する高度な機能が装備されています。 Connectionインタフェースは、次の2種類のメソッドをサポートしています。

接続の停止および再開機能は、広範囲のアプリケーションで使用できる非常に便利な機能です。 たとえば、この機能をインタラクティブアプリケーション(GUIアプリケーションなど)で使用すると、ユーザは、組み込まれたJMS機能を使用してメッセージのフローを開始および停止できます。

接続コンシューマ

すでに説明したとおり、セッションによりメッセージの送信と受信に対するシングルスレッドが提供されます。 つまり、receivereceiveNoWait、およびonMessageへのすべての呼び出しは、特定セッション内のすべてのコンシューマに対してシリアル化されます。 この機能は通常、スレッドセーフなコンシューマを安心して作成できるため、アプリケーション開発者には非常に便利です。

ただし、コンシューマアプリケーションによりJMSプロバイダに対する複数の接続が作成されない限り、基礎となるJVMおよびハードウェアの並行処理機能を利用して、クライアントアプリケーションが処理できるメッセージ数を最高にできないということにもなります。 接続はリソースをかなり消費するオブジェクトであるため、接続を多数作成することはお勧めできません。

コンシューマアプリケーションでの高度な並行処理機能が必要な場合に備え、JMS仕様では、接続コンシューマと呼ばれるオプションのJMS機能が定義されています。 接続コンシューマは、セッションレベルではなく接続レベルで「機能」します。そのため、セッションの並行処理制限に影響されません。

ConnectionConsumerは、メッセージを同時に処理できるオブジェクトです。 接続コンシューマは、TopicConnectionまたはQueueConnectioncreateConnectionConsumerまたはcreateDurableConnectionConsumerメソッドを使用して作成されます。 接続コンシューマは、背後でServerSessionPoolに依存して、プールにより作成されたセッションオブジェクトのsetMessageListenerメソッドで設定された非同期コンシューマにメッセージを配信します。

次の図は、接続コンシューマ、サーバセッションプール、およびセッションの関係を示しています。 サーバセッションプールは、異なるスレッドで実行する複数のセッションを作成できるため、このアーキテクチャでは単一の接続を使用して、メッセージを同時に配信することができます。 セッションで分散トランザクション(XASession)がサポートされている場合、セッションのメッセージリスナは、オプションで、XAResourceを呼び出して、トランザクションによりメッセージを配信できます。

JMSプロバイダは、次の手順を実行して、接続コンシューマを使用したメッセージ配信を処理します。

  1. 最初に、接続コンシューマはメッセージの送信元となるいくつかの宛先に接続します。
  2. 宛先からいくつかのメッセージを受信すると、サーバセッションプールからサーバセッションを取得します。 理論上は、サーバセッションはスレッドで、サーバセッションプールはスレッドプールです。
  3. 接続コンシューマは、サーバセッションからセッションを取得します。
  4. JMSプロバイダのプライベートAPIを使用して、接続コンシューマは、そのメッセージをセッションに割り当てることができます。 この手順は、JMSプロバイダにより自動的に実行されます。
  5. 接続コンシューマは、サーバセッションでstartメソッドを呼び出します。
  6. 次に、サーバセッションは、そのセッションでrunメソッドを呼び出す必要があります。 SessionRunnableインタフェースを実装するため、任意のスレッドで実行できます。
  7. セッションのrunメソッドは、そのメッセージをセッションメッセージリスナに配信します。 前に説明したとおり、リスナは、オプションで、セッションのXAResourceを呼び出して、トランザクションによりメッセージ配信を制御できます。

要約すると、接続コンシューマアーキテクチャでは、ユーザは、メッセージを同時に配信できるだけでなく、実際に作業を実行するスレッドを制御することもできます。 このアーキテクチャは、メッセージ駆動型Beanを実装するアプリケーションサーバを主な対象としていますが、上級のアプリケーション開発者でも使用することができます。

分散トランザクション

分散トランザクションは、メッセージの送信または確認タスクを分散システムで実行している他のタスクと統合できるため、トランザクションセッションよりも優れています。 たとえば、メッセージの確認は、メッセージをデータベースに保存する場合と同じ作業単位で実行できます。

分散トランザクションは、ACIDのプロパティをサポートしています。

ACIDプロパティは、2段階コミット(2PC)プロトコルを使用して分散トランザクションを駆動することにより実行されます。 2PCプロトコルは、リソースコーディネータ(トランザクションマネージャ)と呼ばれるミドルウェアで制御されます。 リソースコーディネータは、次のアクションを実行することで2段階コミットを制御します。

  1. 最初に、トランザクション内のすべてのリソースを準備するよう要求されます。 リソースが準備されると、トランザクションの処理を開始し、完了する準備ができたことになります。 いずれかのリソースが準備できないと、トランザクションは中断(ロールバック)します。
  2. 第1段階が成功し、すべてのリソースが準備されると、第2段階が開始されます。 ここでは、すべてのリソースをコミットするよう要求されます。 リソースコーディネータは、すべてのリソースが成功するまでコミットを呼び出します。

メッセージを送信し、同じメッセージを受信するという操作を1つの分散トランザクションで行うことはできません。これは、このような動作が前に説明したACIDのプロパティ(孤立)に違反するからです。 宛先へのメッセージの入力、および宛先からのメッセージの削除は、2つの別々な操作なので、2つの異なるトランザクションで実行する必要があります。

前に説明したとおり、グローバルトランザクションでは、トランザクションに参加するリソースを追跡するコーディネータが必要です。 このコーディネータは、クラッシュが発生した場合にリソースの状態を記録するので、2段階コミットプロトコルが確実に完了(コミットまたはロールバック)されます。 コーディネータは、jBroker MQには搭載されていない別の製品です。

JMSが、コーディネータ(JTS/JTA)をサポートしているアプリケーションサーバのコンテキスト内で使用される場合、XAResourceオブジェクトの適切な処理は、コンテナにより自動的に行われます。 通常、アプリケーションプログラマは、JMSリソースの追加、削除、および駆動作業が自動的に行われるような制御された環境では、分散トランザクションの使用を選択します。


Copyright © 1998-2003,
Novell, Inc. All rights reserved.