【问题标题】:Jms message acknowledge only till the message acknowledged onJms 消息只确认,直到消息确认
【发布时间】:2012-01-13 19:46:48
【问题描述】:

如何确保消息确认仅删除消息,直到在 jms 代理中调用确认的消息为止。 目前我有一个系统,它从 jms 队列中消耗并部分处理它。稍后,一批这些消息被另一个线程持久化。我现在需要确认消息。但问题是我必须停止使用消息,否则确认先前收到的消息也会确认收到的所有其他后续消息。

换句话说,假设我在一个队列中有 10 条消息。我消耗了其中的 7 个,然后在第 5 条消息上确认。这反过来会从队列中删除消费者收到的所有 7 条消息。有没有办法只确认并从队列中删除消息,直到第 5 条消息。

编辑:我尝试创建两个会话并从不同的会话中使用,但是(至少使用 apache qpid)这执行不一致。我的意思是不一致,有时在测试过程中,一个消费者能够接收消息,而另一个消费者根本没有收到消息,无论您等待多长时间。这对我来说是一种解决方案,但由于不一致,无法将其用作解决方案。

【问题讨论】:

  • 您尚未指定您使用的消息提供程序。但据我所知,许多消息传递提供商不允许随机消息确认。如果您确认一条消息,则在此之前收到的所有消息也将被确认并从队列中删除
  • 我使用 apache qpid,我不是随机确认,而是对特定消息进行确认。如果在此之前的所有消息都被清除就可以了,但如果收到更多消息,它们也会被删除。

标签: java jms messaging qpid


【解决方案1】:

我知道这篇文章已经过时了,但是这个答案应该对以后偶然发现它的人有所帮助。

如果您想对要确认的消息进行细粒度控制,individual 确认方法应该可以帮助您。使用此确认模式,您可以确认会话中的单个消息。未确认的消息将被重新发送。

这不是规范的一部分,但大多数队列提供程序在规范之外支持它。

Oracle

为了获得更大的灵活性,Message Queue 允许您自定义 JMS 客户确认模式。在客户端确认模式下,客户端 通过调用 消息对象的确认()方法。

的标准行为 此方法是使会话确认所有消息 自上次以来已被会话中的任何消费者消费 该方法被调用。 (也就是说,会话确认当前 消息和所有以前未确认的消息,无论是谁 消耗掉它们。)

除了 JMS 指定的标准行为之外,Message Queue 允许您使用客户端确认模式来确认一条消息 时间。

public interface com.sun.messaging.jms.Message {
          void acknowledgeThisMessage() throws JMSException;
          void acknowledgeUpThroughThisMessage() throws JMSException;
}

ActiveMQ

可以想象其他有用的确认模式,因为 示例: CONSUMER_ACKNOWLEDGE 其中 Message.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

在处理批处理时,您可以确认接收和处理的每条消息。如果遇到异常,请不要确认消息。

【讨论】:

    【解决方案2】:

    确认消息将使队列管理器删除该消息以及在该消息之前收到的所有其他消息。它不应该删除应用程序尚未收到的消息。您可能想检查您的应用程序如何确认消息。

    【讨论】:

    • 问题是消费者收到的所有消息都被删除了,它不依赖于你正在确认的消息。我想实现一些只删除特定消息的东西,即使在那之后我可能会收到更多消息。这是必需的,因为我批量处理消息,并且每当批处理完成时,我需要确认该批次。而且这个批处理很耗时,所以我想继续并行接收消息
    • 不,这是不可能的。当一条消息被确认时,所有收到的消息都将被删除。您可能需要寻找替代方案。
    猜你喜欢
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2012-05-10
    相关资源
    最近更新 更多