如何在一个线程中连续读取JMS消息并根据另一个线程中的JMSMessageID来创建它们?

时间:2012-12-06 12:08:23

标签: jms activemq kettle

我写了一篇连续的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在超时后为空),而它确实存在于队列中。 我怀疑该消息被连续输入线程阻止..事实上,当单独触发AcknowledgeMes​​sage()时,它工作正常。

是否有更清晰的方法来检索1条消息?基于其QueueId和messageId
另外,如果长时间记忆消息或ID,我觉得连续阅读器中可能存在“强烈的内存泄漏风险” ...是否合理?

如果我使用QueueBrowser来避免影响确认线程,看起来我不能拥有这个连续的输入源..对吗?

更多背景信息:我正在使用ActiveMQ,2个线程是Pentaho Kettle转换的2 custom "Steps"
注意:简化了代码示例以关注问题。

1 个答案:

答案 0 :(得分:2)

好吧,你不能两次阅读那条消息,因为你已经在第一个帖子中读过它了。

ActiveMQ不会删除该消息,因为您没有确认它,但是在您删除JMS连接之后它将不可见(我不确定在ActiveMQ中是否存在长时间超时)。

因此您必须使用原始邮件并执行:message.acknowledge();。 但请注意,会话不是线程安全的,因此如果您在两个不同的线程中执行此操作,请务必小心。