1

次のコードを使用して送信者と受信者を作成する場合

qsender = qsession.createSender((Queue)msg.getJMSDestination());
qreceiver=qsession.createReceiver((Queue)msg.getJMSDestination());

そしてこれを行う

qsender.send(msg);

メッセージをキューに送信するだけで、キューに永久に残りますか?受信者でreceive()メソッドを呼び出す必要がありますか、それとも受信者に取得するためにMessageListenerインターフェイスを実装する必要がありますか?

編集:詳細

qsender = qsession.createSender((Queue)msg.getJMSDestination());
qreceiver=qsession.createReceiver((Queue)msg.getJMSDestination());

temp1 = qsession.createTemporaryQueue();
responseConsumer = qsession.createConsumer(temp1);
msg.setJMSReplyTo(temp1);

responseConsumer.setMessageListener(responseListener);
msg.setJMSCorrelationID(msg.getJMSCorrelationID()+i);

qsender.send(msg);

上記のコードで、一時キューは何に使用されますか?メッセージを受信するためですか?レシーバーですか?はいの場合、どのように使用しmsg.setJMSReplyTo(temp1)ますか?

4

2 に答える 2

2

はい、 send(..) メソッドは宛先キューにメッセージを送信します。そして、このメッセージは、プログラムがレシーバーを使用して受信するまで、またはメッセージブローカーが実行されるまで (私が知っているように)、キューに残ります。

2番目の質問について、2つのアプローチの違いは次のとおりです。

receive (..) メソッドは同期的です (これはこのアプローチの欠点です)。これは、メッセージが利用可能になるまで (またはタイムアウト条件が発生するまで) receive () メッセージがブロックされるため、受信者はメッセージが到着するまで辛抱強く待つ必要があることを意味します。リスナーでメッセージを消費する反対側からは、非同期プロセスです。受信者は待機しません。リスナーは、メッセージがクエリに送信されるときにのみ受信メソッドを呼び出します。

アップデート:

一時宛先は、コンシューマーによるメッセージの返信を送信するために使用されます。たとえば、サーバーがクライアントからメッセージを受け取り、クライアントに応答を送信する必要がある場合があります。そのような場合は、一時宛先を使用する必要があります。サーバー アプリケーションは、クライアントに応答メッセージを送信するために、この一時的な送信先 (この場合はキュー) を使用します。このようなキューには、それを作成した接続に限定されたスコープがあり、接続が閉じられるとすぐにサーバー側で削除されます。

詳細については、この記事公式の Java チュートリアルを参照してください。2 番目の記事では、JMSCorrelationID をいつどのように使用するかについても説明します。

一時的な宛先を使用して応答メッセージを送信する方法を説明する公式ドキュメントの興味深い部分を次に示します。

一時的な宛先を使用して、単純な要求/応答メカニズムを実装できます。一時的な送り先を作成し、それをメッセージの送信時に JMSReplyTo メッセージ ヘッダー フィールドの値として指定すると、メッセージのコンシューマは、応答の送り先として JMSReplyTo フィールドの値を使用できます。コンシューマーは、応答メッセージの JMSCorrelationID ヘッダー フィールドを要求の JMSMessageID ヘッダー フィールドの値に設定することによって、元の要求を参照することもできます。たとえば、onMessage メソッドは、受信したメッセージに返信できるようにセッションを作成できます。次のようなコードを使用できます。

producer = session.createProducer(msg.getJMSReplyTo());
replyMsg = session.createTextMessage("Consumer " +
    "processed message: " + msg.getText());
replyMsg.setJMSCorrelationID(msg.getJMSMessageID());
producer.send(replyMsg);

更新 2:

キュー (またはトピック) でのメッセージの有効期限について、回答を明確にしたいと思います。デフォルトでは、メッセージは期限切れになりません。ただし、メッセージの有効期限を設定できます。

producer.setTimeToLive(60000);

この後、この MessageProducer によって生成されたすべてのメッセージには、有効期限が指定されます。

また、送信中に具体的なメッセージの有効期限を指定できます。

producer.send(message, DeliveryMode.NON_PERSISTENT, 3, 10000);

ここで、10000 は 10 秒を意味します

于 2012-08-16T06:27:17.510 に答える
2
  1. はい、消費されるか、手動または強制的にキューから削除されるまで、常にキューに残ります。これが JMS の耐久性に関するものであり、それが RPC よりも優先される理由です。

  2. receive メソッドについては、同期メソッドであり、消費されるメッセージを受信するまでスレッドをブロックします。

  3. Message Listener の実装については、pull ベースのモデルに従います。メッセージ ブローカは、消費されるメッセージがあるかどうかを確認するために、しばらくしてから JMS サーバーへのクエリを続けます。

  4. オプション 3 とオプション 4 のどちらを選択するかは、要件によって異なります。スレッドをブロックすることには独自の欠点があり、それ以上何も進めません。また、ポーリングには独自の欠点があります。特に、Jms サーバーがリモート マシン上でスタンドアロン サーバーとして実行されている場合は、ブローカーは、しばらくしてから RMI を使用してメッセージを照会する必要があります。

更新 ::エンタープライズ統合の Request/Reply パターンEIPを見ると、メッセージングが非同期プロセスを使用しているため、相手側からの確認応答がないことが説明されています。メッセージに関する受信確認を送信者に送り返したい場合は、受信msg.setJMSReplyTo確認メッセージ相関 ID を使用して送信者メッセージ ID と照合し、要求応答を同期することができます。

一時キューに来ると、展開時にキューを静的に定義するのではなく、実行時にキューを作成し、特定の接続にバインドするという利点があります。利点は、軽量の代替手段を提供し、システムをスケーリングするのに役立つことです。かなりの程度。

于 2012-08-16T06:52:29.240 に答える