1

私は継続的な JMS メッセージ受信者を書きました: ここでは、このスレッドにメッセージを確認させたくないので、CLIENT_ACKNOWLEDGE を使用しています。

(...)
connection.start();
session = connection.createQueueSession(true, Session.CLIENT_ACKNOWLEDGE);
queue = session.createQueue(QueueId);
receiver = session.createReceiver(queue);
While (true) {
  message = receiver.receive(1000);
  if ( message != null ) {
    // NB : I can only pass Strings to the other thread
    sendMessageToOtherThread( message.getText() , message.getJMSMessageID() ); 
  }
  // TODO Implement criteria to exit the loop here
}

別のスレッドで、次のようにします (処理が成功した後):
これは、同時に実行される別個の JMS 接続にあります。

public void AcknowledgeMessage(String messageId) {
  if (this.first) {
    this.connection.start();
    this.session = this.connection.createQueueSession( false, Session.AUTO_ACKNOWLEDGE );
    this.queue = this.session.createQueue(this.QueueId);
  }
  QueueReceiver receiver = this.session.createReceiver(this.queue, "JMSMessageID='" + messageId + "'");
  Message AckMessage = receiver.receive(2000);
  receiver.close();
}

メッセージが見つからない ( AckMessage はタイムアウト後に null になる) のに、キューには存在するようです。メッセージが連続入力スレッドによってブロックされていると思われます..実際、AcknowledgeMes​​sage() を単独で起動すると、正常に動作します。

1 メッセージを取得するよりクリーンな方法はありますか? その QueueId と messageId に基づいてまた、メッセージや ID を長時間記憶しなければならない場合、継続的なリーダーでメモリ リーク
のリスクがあるように感じます..正当化されますか?

承認スレッドへの影響を避けるためにを使用している場合QueueBrowser、この連続入力フィードを使用できないようです..そうですか?

詳細なコンテキスト: 私はActiveMQを使用しており、2 つのスレッドはPentaho Kettle 変換の2 つのカスタム「ステップ」です。
注意: コード サンプルは、問題に焦点を当てるために単純化されています。

4

1 に答える 1

2

最初のスレッドで既に読んでいるので、そのメッセージを 2 回読むことはできません。

確認していないため、ActiveMQ はメッセージを削除しませんが、JMS 接続をドロップするまで表示されません (ActiveMQ にも長いタイムアウトがあるかどうかはわかりません)。

したがって、元のメッセージを使用して、次のことを行う必要がありますmessage.acknowledge();。ただし、セッションはスレッドセーフではないため、2 つの異なるスレッドでこれを行う場合は注意してください。

于 2012-12-06T12:23:41.367 に答える