Javaを紐解くための重点キーワード
伊藤敬
日本BEAシステムズ
2001/11/7
JMS(Java Message Service) |
■JMSとは?
JMSは通称「MOM」(メッセージ指向ミドルウェア)と呼ばれるエンタープライズメッセージングシステムにアクセスするための標準APIです。つまり、メッセージングシステムそのものの実装ではなく、MOMのサービスを利用するためのJavaベースの標準インターフェイスであるということです。JMSで定義されている仕様はベンダ・ニュートラルであり、どのMOMにアクセスする場合でも、一部の属性のみに個別の情報を定義するだけで、JMSアプリケーション自身は共通の手順と構成でシステム構築を進めることができます。
また、JMSを利用することで複数のアプリケーションがメッセージの交換を通じて通信することができるようになります。そのメッセージング形態はピア・ツー・ピア型であり、JMSアプリケーションは通常「クライアント」に位置付けられます。JMSはJ2EEのほかのサービス(JTA/JTS、JNDI、JDBCなど)と連携し、Servlet/JSP、EJBのアプリケーションに組み込むことができます。また、EJB 2.0で定義されたメッセージドリブンBeanでは、JMSとの連携によって非同期型のEJBアプリケーションを作成できます。
JMSの特徴をまとめると以下のようになります。
- Javaアプリケーション間で既存のMOMを共有し、メッセージを送受信できる
- メッセージを作成、送受信するための標準インターフェイスが提供されることによりメッセージ・アプリケーションの開発が容易になる
- 既存のMOM製品群を横断的にカバーするアーキテクチャの提供により、メッセージング・アプリケーションのポータビリティが向上する
■JMSのメッセージングモデル
MOM製品の主要なメッセージングモデルにポイント・ツー・ポイント(PTP)およびパブリッシュ/サブスクライブ(Pub/Sub)があります。PTPはメッセージキューのコンセプトに基づいており、1つのあて先に対して1つの送信元からメッセージが送信されます。Pub/Subは階層化されたノードに定義された複数のクライアントに1つの送信元からメッセージを配信します。JMSはこの2つのメッセージングモデルをサポートしており、システム構築に必要なクライアントインターフェイスを提供しています。
■PTPメッセージングモデル
PTPメッセージングモデルでは、アプリケーションが別の1つのアプリケーションにメッセージを送信できます。PTPアプリケーションでは、名前付きキューを使用してメッセージが送受信されます。キューセンダ(プロデューサ)は、特定のキューに対してメッセージを送信し、以下の図のように、キューレシーバ(コンシューマ)は、特定のキューからメッセージを受信します。
PTPメッセージングモデル |
複数のキューセンダおよびキューレシーバを1つのキューに関連付けることができますが、個々のメッセージは1つのキューレシーバにしか配信できません。
■Pub/Subメッセージングモデル
Pub/Subメッセージングモデルでは、アプリケーションが複数のアプリケーションにメッセージを送信できます。Pub/Subアプリケーションでは、トピックをサブスクライブすることでメッセージが送受信されます。以下の図のように、トピックパブリッシャ(プロデューサ)では、特定のトピックに対してメッセージが送信されます。トピック・サブスクライバ(コンシューマ)では、特定のトピックからメッセージが受信されます。
Pub/Subメッセージングモデル |
PTPメッセージングモデルの場合と違って、Pub/Subメッセージングモデルでは複数のトピックサブスクライバが同じメッセージを受信できます。メッセージは、すべてのトピックサブスクライバが受信するまで維持されます。
■JMSのアーキテクチャ
JMSアプリケーションの基本構成は以下のとおりです。
JMSアプリケーションの基本構成 |
さらに、前述のとおり、JMSでは異なるMOMのサービスを共通化して利用するためにメッセージ通信に関する属性定義をカプセル化しています。そのために以下のオブジェクトが用意されています。
管理オブジェクト
JNDIに登録されるオブジェクトであり、JMSクライアントがルックアップすることでJMSのサービスを利用できるようにします。管理オブジェクトは、JMSクライアントがJMSプロバイダに接続するために必要な属性情報を管理します。JMSプロバイダは通常、管理オブジェクトに属性を定義するためのツールを提供します。
さらに、JMSにはConnectionFactoryとDestinationと呼ばれる管理オブジェクトが定義されています。
ConnectionFactoryオブジェクト
ConnectionFactoryオブジェクトはJMS管理者によって定義された属性情報(JMSプロバイダが存在するホスト名、ポート番号、接続するクライアントIDなど)の集合をカプセル化します。JMSクライアントはConnectionFactoryオブジェクトを利用してJMSプロバイダとの接続を確立します。ConnectionFactoryインターフェイスは、JMSクライアントがConnectionを作成できるようにします。
Destinationオブジェクト
JMSには既存のMOM製品が持つ固有の属性をカプセル化したDestinationオブジェクトが定義されています。これによって属性を単一のものにブリッジし、JMSクライアントのメッセージを送受信します。javax.jms.Destinationインターフェイスのサブクラスとしてjavax.jms.Queueとjavax.jms.Topicが定義されています(ほかにもありますがここでは割愛します)。これらのサブクラスにPTPメッセージングモデルとPub/Subメッセージングモデルに使用するメソッド群が定義されています。DestinationオブジェクトがJMSプロバイダとしてメッセージを送受信するQueueやTopicの実体です。QueueおよびTopicにはそれぞれのメッセージングモデルにのっとったルールが組み込まれており、提供されるメソッドを利用することによってそのルールに沿ったメッセージングを実現できます。
Connectionオブジェクト
Connectionオブジェクトは、JMSアプリケーションとメッセージングシステムの間の通信チャネルを表し、メッセージを生成し送受信するためのSessionオブジェクトを作成するために使用します。Connectionオブジェクトでは、JMSアプリケーションとJMSの間のメッセージングを管理するサーバサイドとクライアントサイドのオブジェクトが作成されます。Connectionオブジェクトは、PTPとPub/Subに対応するインターフェイスを持っており、それぞれjavax.jms.QueueConnection、javax.jms.TopicConnectionで定義され、コネクションの状態をコントロールするメソッドなどを含めたJMSクライアントとJMSプロバイダの接続状態を管理します。
Sessionオブジェクト
Sessionオブジェクトでは、生成および送受信されるメッセージの順序を定義し、複数のMessageProducerとMessageConsumerを作成できます。
MessageProducer/MessageConsumerオブジェクト
MessageProducerオブジェクトでは、メッセージがQueueまたはTopicに送信されます。MessageConsumerオブジェクトでは、メッセージがQueueまたはTopicから受信されます。2つのオブジェクトは互いに独立して機能します。MessageConsumerが作成されてメッセージを待っているかどうかに関係なく、MessageProducerではメッセージが生成および送信されます。この逆も同様です。
メッセージセンダオブジェクトとメッセージレシーバオブジェクトは、MessageProducer クラスおよびMessageConsumerクラスのサブクラスとして作成されます。次の表は、MessageProducerとMessageConsumerのサブクラスを説明しています。
サブクラス | メッセージングモデル | 機能 |
QueueSender | PTP | JMS PTPプロバイダのメッセージを送信する |
QueueReceiver | PTP | JMS PTPプロバイダのメッセージを受信し、メッセージの作成されたJMS接続が閉じるまで存続する |
TopicPublisher | Pub/Sub | JMS Pub/Subプロバイダのメッセージを送信する |
TopicSubscriber | Pub/Sub | JMS Pub/Subプロバイダのメッセージを受信し、メッセージの作成されたJMS接続が閉じるまで存続する。メッセージの送り先は、適切なJNDIインターフェイスを使用して明示的にバインドしなければならない |
これまでに紹介したJMSアプリケーションを構成するオブジェクトやサービスを以下の図にまとめます。
JTA/JTSとそれに関連するサービス |
■JMSのメッセージ
JMSアプリケーションで送受信されるのはMessageオブジェクトです。このオブジェクトはアプリケーション間で交換される情報がカプセル化されており、標準のメッセージヘッダフィールド、アプリケーション固有のプロパティ、およびメッセージ本文という3つの要素で構成されます。
メッセージヘッダフィールド
すべての JMSメッセージには、デフォルトで挿入され、MessageConsumerで利用できる標準のヘッダフィールドがあります。一部のフィールドは、MessageProducerで設定できます。
メッセージプロパティフィールド
メッセージのプロパティフィールドには、メッセージプロデューサによって追加されたヘッダフィールドが格納されます。プロパティは、標準的なJavaの名前と値の組み合わせです。有効な値は、boolean、byte、double、float、int、long、およびstring
です。
メッセージ本文
メッセージ本文は、プロデューサからコンシューマに配信される内容です。メッセージ本文が扱えるのは、テキスト、Javaオブジェクト、ストリームデータなどです。
JMSアプリケーションの開発
これまで説明した内容を踏まえて、JMSアプリケーションの開発は以下のような手順で行う必要があります。
- 必要なパッケージのインポート
- JMSアプリケーションの設定
- メッセージの送信、受信、および確認応答
- リソースのクローズとリリース
JMSアプリケーションの設定
メッセージを送受信するには、あらかじめ JMSアプリケーションを設定しておく必要があります。以下に、JMSアプリケーションの設定に必要な手順を示します。
(例 : Pub/Subアプリケーション)
以下のサンプルは、JMSアプリケーションのトピックセッションをどのように設定して開始するかを示すものです。
/* 必要な変数(JNDIコンテキストなど)、JMS接続ファクトリ、およびトピック静的変数を定義
*/ protected TopicConnectionFactory
tconFactory; |
■メッセージの送信
メッセージをDestinationオブジェクトに送信するには、メッセージセンダオブジェクト(QueueSender(PTP)またはTopicPublisher(Pub/Sub))を使用します。
(例 : Pub/Subアプリケーションにおけるメッセージの送信)
以下の例では、TextMessageオブジェクトを作成し、テキストベースのメッセージを設定した後、Topicに送信するために必要なコードを示してあります。
msg = tsession.createTextMessage(); |
■メッセージの受信
メッセージを受信するには、メッセージレシーバオブジェクトを作成し、メッセージを同期受信するか非同期受信するかを指定する必要があります。
メッセージの非同期受信
非同期受信を行う場合、JMSアプリケーションの設定時のメッセージプロデューサとメッセージの作成を以下のコードに変更します。
tpublisher = tsession.createPublisher(topic);
|
↓
tsubscriber = tsession.createSubscriber(topic);
/* トピックサブスクライバを作成 */ |
メッセージがトピックセッションに届くと、そのメッセージはonMessageメソッドに渡されます。以下はonMessageメソッドでの処理の1例です。
public void onMessage(Message msg) |
メッセージの同期受信
メッセージを同期的に受信するには、recieveメソッドを使用します。receiveメソッドを引数なしで呼び出した場合、その呼び出しはメッセージが生成されるか、またはアプリケーションが閉じられるまで無期限にブロックされます。代わりに、タイムアウト値を渡してメッセージの待ち時間を指定することもできます。
(例 : Pub/Subアプリケーション内でのメッセージの同期受信)
以下の例ではreceiveメソッドを呼び出してメッセージ受信まで無期限に待機します。
tsubscriber = tsession.createSubscriber(topic);
/* Topicに対するトピックサブスクライバの作成 */ |
Javaを紐解くための重点キーワード |
- 実運用の障害対応時間比較に見る、ログ管理基盤の効果 (2017/5/9)
ログ基盤の構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。今回は、実案件を事例とし、ログ管理基盤の有用性を、障害対応時間比較も交えて紹介 - Chatwork、LINE、Netflixが進めるリアクティブシステムとは何か (2017/4/27)
「リアクティブ」に関連する幾つかの用語について解説し、リアクティブシステムを実現するためのライブラリを紹介します - Fluentd+Elasticsearch+Kibanaで作るログ基盤の概要と構築方法 (2017/4/6)
ログ基盤を実現するFluentd+Elasticsearch+Kibanaについて、構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。初回は、ログ基盤の構築、利用方法について - プログラミングとビルド、Androidアプリ開発、Javaの基礎知識 (2017/4/3)
初心者が、Java言語を使ったAndroidのスマホアプリ開発を通じてプログラミングとは何かを学ぶ連載。初回は、プログラミングとビルド、Androidアプリ開発、Javaに関する基礎知識を解説する。
|
|