我写了一篇连续的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在超时后为空),而它确实存在于队列中。 我怀疑该消息被连续输入线程阻止..事实上,当单独触发AcknowledgeMessage()时,它工作正常。
是否有更清晰的方法来检索1条消息?基于其QueueId和messageId
另外,如果长时间记忆消息或ID,我觉得连续阅读器中可能存在“强烈的内存泄漏风险” ...是否合理?
如果我使用QueueBrowser
来避免影响确认线程,看起来我不能拥有这个连续的输入源..对吗?
更多背景信息:我正在使用ActiveMQ,2个线程是Pentaho Kettle转换的2 custom "Steps"。
注意:简化了代码示例以关注问题。
答案 0 :(得分:2)
好吧,你不能两次阅读那条消息,因为你已经在第一个帖子中读过它了。
ActiveMQ不会删除该消息,因为您没有确认它,但是在您删除JMS连接之后它将不可见(我不确定在ActiveMQ中是否存在长时间超时)。
因此您必须使用原始邮件并执行:message.acknowledge();
。
但请注意,会话不是线程安全的,因此如果您在两个不同的线程中执行此操作,请务必小心。