JMS/ Introduction to JMS

JMS
通称「MOM」(メッセージ指向ミドルウェア)
と呼ばれるエンタープライズメッセージングシステムにアクセスするための標準API
つまり
MOMのサービスを利用するための ベンダ・ニュートラルの Javaベースの標準インターフェイス群

JMSの特徴
* Javaアプリケーション間で既存のMOMを共有し メッセージを送受信できる
* メッセージを作成 送受信するための標準インターフェイスで メッセージ・アプリケーションの開発が容易になる
* 既存のMOM製品群を横断的にカバーするアーキテクチャで メッセージング・アプリケーションのポータビリティが向上する


JMSのメッセージングモデル
MOM製品の主要なメッセージングモデル:
*ポイント・ツー・ポイント(PTP)
*パブリッシュ/サブスクライブ(Pub/Sub)
PTP
1つのあて先に対して1つの送信元からメッセージが送信される
Pub/Sub
階層化されたノードに定義された複数のクライアントに1つの送信元からメッセージを配信する


■PTPメッセージングモデル
名前付きキューを使用してメッセージが送受信される
キューセンダ(プロデューサ)は
特定のキューに対してメッセージを送信し キューレシーバ(コンシューマ)は
特定のキューからメッセージを受信する

複数のキューセンダおよびキューレシーバを1つのキューに関連付けられるが
個々のメッセージは1つのキューレシーバにしか配信できない

■Pub/Subメッセージングモデル
トピックをサブスクライブすることでメッセージが送受信される
トピックパブリッシャ(プロデューサ)は
特定のトピックに対してメッセージを送信する
トピック・サブスクライバ(コンシューマ)は
特定のトピックからメッセージが受信される

複数のトピックサブスクライバが同じメッセージを受信でき
メッセージは
すべてのトピックサブスクライバが受信するまで維持される


JMSのアーキテクチャ
JMSクライアント:
メッセージを送受信する個々のJavaプログラム
メッセージ・プロデューサ=メッセージ送信側
メッセージ・コンシューマ=メッセージ受信側
JMSプロバイダ:
JMSインターフェイスを実装し
かつ管理機能なども装備したメッセージングシステムそのもの
もしくはMOMのサービスをJ2EE側に提供する実装
JMSメッセージ:
JMSクライアント間で情報の受け渡すための個々のアプリケーションで定義されるリクエスト/レポート/イベント


プラス
ベンダニュートラルのため
メッセージ通信に関する属性定義は
オブジェクトとしてカプセル化されて管理される

管理オブジェクト
JNDIに登録されるオブジェクト
JMSクライアントがルックアップすることでJMSのサービスを利用できる
管理オブジェクトは
JMSクライアントがJMSプロバイダに接続するために必要な属性情報を管理する


ConnectionFactoryオブジェクト
管理オブジェクトの1つ
JMS管理者によって定義された属性情報(JMSプロバイダが存在するホスト名、ポート番号、接続するクライアントIDなど)の集合をカプセル化する
JMSクライアントは
ConnectionFactoryオブジェクトを利用してJMSプロバイダとの接続を確立する
ConnectionFactoryインターフェイスは、JMSクライアントがConnectionを作成できるようにする


Destinationオブジェクト
管理オブジェクトの1つ
既存のMOM製品が持つ固有の属性をカプセル化する
javax.jms.Destinationインターフェイスのサブクラスとして
javax.jms.Queue
javax.jms.Topic
等がある


Connectionオブジェクト
JMSクライアントとJMSプロバイダの接続状態を管理する
JMSアプリとメッセージングシステム間の通信チャネルを表していて
メッセージを生成し送受信するためのSessionオブジェクトを作成するために使用される
Connectionオブジェクトには
PTPとPub/Subに対応する
javax.jms.QueueConnection
javax.jms.TopicConnection
がある


Sessionオブジェクト
生成および送受信されるメッセージの順序を定義し
複数のMessageProducerとMessageConsumerを作成できる


MessageProducer/MessageConsumerオブジェクト
MessageProducerオブジェクト:
メッセージをQueue/Topicに送信する
MessageConsumerオブジェクト:
メッセージがQueue/Topicから受信する
2つのオブジェクトは互いに独立して機能する


メッセージセンダオブジェクト&メッセージレシーバオブジェクト
MessageProducerクラスおよびMessageConsumerクラスのサブクラスとして作成される


■JMSのメッセージ
Messageオブジェクト
アプリケーション間で交換される情報がカプセル化されており
標準のメッセージヘッダフィールド
アプリケーション固有のプロパティ
メッセージ本文
という3つの要素で構成される

メッセージヘッダフィールド
JMSメッセージにデフォルトで挿入される MessageConsumerで利用できる標準のヘッダフィールド
MessageProducerからも設定できる

メッセージプロパティフィールド
メッセージプロデューサによって追加されたヘッダフィールド
標準的なJavaの名前と値の組み合わせでなる
メッセージ本文
プロデューサからコンシューマに配信される内容


JMSアプリケーションの開発手順
1. 必要なパッケージのインポート
2. JMSアプリケーションの設定
3. メッセージの送信、受信、および確認応答
4. リソースのクローズとリリース

■JMSアプリケーションの設定(Pub/Subアプリの場合)

/* 必要な変数(JNDIコンテキストなど)、JMS接続ファクトリ、およびトピック静的変数を定義 */
public final static String JNDI_FACTORY = "javax.jndi.InitialContextFactory";
public final static String JMS_FACTORY = "javax.jms.TopicConnectionFactory";
public final static String TOPIC = "javax.jms.Topic";

protected TopicConnectionFactory tconFactory;
protected TopicConnection tcon;
protected TopicSession tsession;
protected TopicPublisher tpublisher;
protected Topic topic;
protected TextMessage msg;

InitialContext ic = getInitialContext(args[0]); /* JNDI 初期コンテキストを設定 */

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

/* JMSトピックにメッセージを送信するために必要なすべてのオブジェクトを作成 */
public void init(Context ctx/* JNDI 初期コンテキスト */, String topicName) throws NamingException, JMSException{
tconFactory = (TopicConnectionFactory) ctx.lookup(JMS_FACTORY); /*JNDIを使用してConnectionFactoryをルックアップ */
tcon = tconFactory.createTopicConnection(); /*ConnectionFactoryを使用してConnectionを作成 */
tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); /*Connectionを使用してSession(この場合は非トランザクション)を作成 */

topic = (Topic) ctx.lookup(topicName); /*JNDIを使用してDestination(Topic)をルックアップ */
tpublisher = tsession.createPublisher(topic); /*SessionとDestination(Topic)を使用してメッセージセンダオブジェクト(TopicPublisher)への参照を作成 */
msg = tsession.createTextMessage(); /* メッセージオブジェクトを作成 */
tcon.start(); /* 接続を開始 */
}

■メッセージの送信(Pub/Subアプリの場合)

msg = tsession.createTextMessage();

public void send(String message) throws JMSException{
msg.setText(message);
tpublisher.publish(msg); /* トピックパブリシャ・オブジェクトのPublishメソッドで送信 */
}

■メッセージの受信
メッセージを受信するには
メッセージレシーバオブジェクトを作成し
メッセージを同期受信するか非同期受信するかを指定する必要がある

□メッセージの非同期受信
tsubscriber = tsession.createSubscriber(topic); /* トピックサブスクライバを作成 */
tsubscriber.setMessageListener(msgListener); /* 非同期メッセージリスナを登録 */
*msgListener
public void onMessage(Message msg){
try {
String msgText = null;
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();
}
}

□メッセージの同期受信
メッセージを同期的に受信するには
recieveメソッドを使用する
receiveメソッドを引数なしで呼び出した場合
メッセージが生成されるか
または
アプリケーションが閉じられるまで無期限にその呼び出しが ブロックされる
代わりに
タイムアウト値を渡してメッセージの待ち時間を指定することも可

tsubscriber = tsession.createSubscriber(topic); /* Topicに対するトピックサブスクライバの作成 */
Message msg = tsubscriber.receive(); /* メッセージ受信まで無期限にメッセージ待機 */
msg.acknowledge();


ref:
Javaを紐解くための重点キーワード:JMS, 2001/11/7
http://www.atmarkit.co.jp/fjava/keyword/jkey/jkey06.html

tag : JMS

2009-10-21 00:24 : __j2ee__jms : コメント : 0 : トラックバック : 0 :
コメントの投稿
非公開コメント

« next  ホーム  prev »

search

ad



counter


tag cloud

category cloud