web-dev-qa-db-ja.com

JMSの「同期」および「非同期」メッセージングを理解するにはどうすればよいですか?

JMSのドキュメントを読んだ後、synchronousasynchronounsというフレーズに戸惑いました。

このページを参照してください: http://docs.Oracle.com/cd/E19798-01/821-1841/bncdq/index.html

同期

Receiveメソッドを使用して、メッセージを同期的に消費します。このメソッドは、startメソッドを呼び出した後であればいつでも使用できます。

_connection.start();
Message m = consumer.receive();
connection.start();
Message m = consumer.receive(1000); // time out after a second
_

メッセージを非同期的に消費するには、次のセクションで説明するメッセージリスナーを使用します。

非同期

JMSメッセージリスナメッセージリスナは、メッセージの非同期イベントハンドラとして機能するオブジェクトです。このオブジェクトは、1つのメソッドonMessageを含むMessageListenerインターフェイスを実装します。 onMessageメソッドでは、メッセージが到着したときに実行するアクションを定義します。

SetMessageListenerメソッドを使用して、メッセージリスナーを特定のMessageConsumerに登録します。たとえば、MessageListenerインターフェイスを実装するListenerという名前のクラスを定義すると、次のようにメッセージリスナーを登録できます。

_Listener myListener = new Listener();
consumer.setMessageListener(myListener);
_

2つの質問があります。

  1. 私が理解したように、JMSの性質は非同期です。プロデューサーはキュー/トピックにメッセージをパブリッシュします。コンシューマーを待つ必要はありません。これは非同期動作です。どのようにして「同期」することができますか?

  2. 「mesageListener」は非同期ですが、spring-jmsを使用したテストでは、常にスレッドで実行されていることがわかりました。つまり、onMessageThread.sleep(2000)を書き込んだ場合、次のメッセージを処理する前に2秒待機する必要があります。 「非同期」ですか?

17
Freewind

このようによく理解すると、consumer.receive()pullモデルを使用します。キューから読み取り、このメッセージが来るか、タイムアウトになるまで、このメッセージを待機するようにブロックされます。

リスナーの使用はPushモデルを使用します。リスナーを登録し、メッセージが到着すると、別のスレッドでリスナーが呼び出されます。

すべてがJavaのスレッドで行われ、リスナーの呼び出しも例外ではありません。リスナーのメッセージ処理がキュー内の他のメッセージの処理を妨げるかどうかは、メッセージ処理専用のスレッドの数によって異なります。 5つのスレッドのプールを使用してメッセージを非同期的に処理するようにSpringを構成すると、5つのリスナーがメッセージを並行して処理できるようになります。

19
JB Nizet

私がこれを理解したように:

asynchronous-MessageListener:キューを待機するサーバーでこれを使用します。メッセージが到着したら、すぐに対処します。サーバーはこのキューをリッスンし続けます。

synchronous-consumer.receive(1000):メッセージをこのクライアント宛てかどうかを時々確認する必要があるクライアントアプリケーションでこれを使用します。例:60秒ごとにポーリングします。これはサーバーへの接続をすぐに開くだけです。 1000ミリ秒は、この接続を開いたままにします。メッセージがこの1000ミリ秒以内に到着すると、メッセージが消費され、接続が閉じられます。

8
Dimitri Dewaele

パブリッシャーからコンシューマーまで、エンドツーエンドで見ています。はい、同期/非同期コンシューマーに関係なく、パブリッシャーからコンシューマーへの非同期配信です。ただし、質問の同期/非同期はコンシューマー専用です。つまり、JMSブローカー(例:ApacheMQ)からコンシューマーへのものです。他の人が指摘したように、同期コンシューマはブローカーからメッセージを順番にプルし、メッセージを待っています。非同期コンシューマーは、メッセージがプッシュされるコールバック(onMessage)を登録します。非同期コンシューマーは、これらのメッセージがJMSブローカーから非同期に配信される間、他のことを実行できます。

3

同期/非同期の解釈が異なります。

Synchronous:Caller(Sender)は、コンシューマからの応答が受信されるまで(タイムアウトになるまで)待機する必要があります-要求/応答パターン

Asynchronous:Caller(Sender)はメッセージをポストして作業を続行しますが、コンシューマーはメッセージが到着するとすぐに処理します-一方向のリクエスト

Any MOM(Message Oriented Middle ware) は、非同期通信を促進するサービスアクティベーターパターンに従います。私のプロジェクトの1つは、JMSの周りにフレームワークを実装して、通信を本当に同期化しました。

  1. メッセージには2つの部分があります。 a。メタデータ属性b。ペイロード
  2. 属性「キューへの返信」をランダムに生成された値に設定します
  3. MOMフレームワークが#2の名前の一時キューを作成することを確認してください
  4. #3で作成された一時キューをリッスンする送信側がスレッドを生成することを確認します
  5. メッセージを発行し、一時キューにメッセージを受信するまで送信者をブロックします
  6. コンシューマが「reply-to-queue」ヘッダーを傍受し、それに応答を発行することを確認します

これは、MOMベースの通信を同期のように機能させる方法の1つです。 request-replyメカニズム のような他の実装を見つけるかもしれません。

0
Nagaraju Koppu