如何确保消息确认仅删除在jms代理中调用确认的消息之前的消息。 目前我有一个系统,它从jms队列中消耗并部分处理它。稍后,一批这些消息被另一个线程持久化。我现在需要对消息表示感谢。但问题是我必须停止使用这些消息,否则确认以前收到的消息也会确认收到的所有其他后续消息。
换句话说,假设队列中有10条消息。我消耗了其中的7个,然后在第5条消息上确认。这反过来会删除消费者从队列中收到的所有7条消息。有一种方法只能确认并从队列中删除消息直到第5条消息。
编辑:我尝试过创建两个会话并从不同的会话中消费,但是(至少使用apache qpid)这会执行不一致的操作。我的意思是不一致,有时在测试期间,无论你等待多久,一个消费者都能够接收消息,而另一个消费者根本不接收消息。这对我来说是一个解决方案,但由于不一致,不能将其作为解决方案。答案 0 :(得分:4)
我知道这篇文章很老了,但是这个答案对那些后来偶然发现它的人有益。
如果您希望对您要确认的邮件进行细粒度控制,individual
确认方法应该会对您有所帮助。使用此确认模式,您可以在会话中确认单个消息。未经确认的消息将被重新传送。
这不是规范的一部分,但大多数队列提供商都支持它超出规范。
为了获得更大的灵活性,Message Queue允许您自定义JMS 客户确认模式。在客户端确认模式下,客户端 通过调用来明确地确认消息消耗 消息对象的acknowledge()方法。
标准行为 此方法是使会话确认所有消息 自上次以来,会话中的任何消费者都已使用过 该方法被调用。 (也就是说,会话确认当前 消息和所有以前未确认的消息,无论是谁 消耗它们。)
除了JMS,Message Queue指定的标准行为 允许您使用客户端确认模式来确认一条消息 时间。
public interface com.sun.messaging.jms.Message {
void acknowledgeThisMessage() throws JMSException;
void acknowledgeUpThroughThisMessage() throws JMSException;
}
可以想象其他认知模式也是有用的 示例:Message.acknowledge()所在的CONSUMER_ACKNOWLEDGE 仅确认在特定MessageConsumer上收到的消息, 或者CONSUMER_CHECKPOINT_ACKNOWLEDGE,Message.acknowledge()会在哪里 仅确认收到的消息,包括消息 调用该方法的实例。
但是没有着手所有这些不同的可能性, 是否可以考虑添加INDIVIDUAL_ACKNOWLEDGE 模式?仅这一点就可以实现多线程应用程序 实现他们需要的任何行为。
connection.createQueueSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
我没有亲自使用QPID,但documentation hints表示个别消息可能是可能的。
Examples
# acknowledge all received messages
session.acknowledge
# acknowledge a single message
session.acknowledge :message => message
处理批处理时,您可以确认收到并处理的每条消息。如果遇到异常,请不要收到消息。
答案 1 :(得分:1)
确认消息将使队列管理器删除该消息以及该消息之前收到的所有其他消息。它不应该删除应用程序尚未收到的消息。您可能需要检查应用程序是否确认消息。