【问题标题】:JMS previous message acknowledgementJMS 上一条消息确认
【发布时间】:2014-05-06 21:43:46
【问题描述】:

我正在尝试解决以下情况:

我正在使用消息,但是在我依赖的系统中发生了中断以进行正确的消息处理(例如数据库)

我正在使用 CLIENT_ACKNOWLEDGE,并且只有在没有抛出异常时才调用 .acknowledge() 方法。

当我抛出异常、消息未被确认并且我可以看到未确认的队列正在建立时,这可以正常工作。但是,这些消息都已经交付给了消费者。

假设现在数据库重新联机,并且任何新消息都已成功处理。所以我打电话给他们 .acknowledge 。我读到调用 .acknowledge() 不仅会确认该消息,还会确认消费者之前收到的所有消息。

这不是我想要的!我需要重新传递/重试这些以前未确认的消息。我想将它们保留在队列中并让 JMS 处理重试,因为在“要重试的消息”的消费者中维护一个 Collection 可能会丢失这些消息(因为 .acknowledge 已经确认了所有这些消息+说硬件故障)。

有没有办法明确地确认特定消息,而不是这种“确认所有先前的消息”行为?

【问题讨论】:

    标签: java jms


    【解决方案1】:

    JMS 规范未定义确认特定消息。因此,一些 JMS 实现者提供每个消息传递确认,而有些则不提供。您将需要检查您的 JMS 提供程序文档。

    消息队列通常可以选择将消息传递给客户端的方式,无论是先进先出 (FIFO) 还是基于优先级。选择 FIFO 选项,以便所有消息按照它们进入队列的相同顺序传递。当数据库下线又回来时,调用recover方法再次以相同的顺序重新传递所有消息。

    【讨论】:

      【解决方案2】:

      在无法从第一条未确认消息重新开始消息传递后,您需要在会话上调用恢复。来自 JMS 1.1 规范第 4.4.11 节

      当使用 CLIENT_ACKNOWLEDGE 模式时,客户端可能会建立一个大 尝试处理它们时未确认的消息的数量。一种 JMS 提供者应该为管理员提供一种限制客户端的方法 过度运行,以便客户不会被驱赶到资源枯竭和 当他们正在使用的某些资源是暂时的时,随之而来的失败 被屏蔽了。

      会话的恢复方法用于停止会话并重新启动它 与它的第一个未确认的消息。实际上,会议的系列 已传递消息的数量被重置为最后一次之后的点 确认消息。它现在传递的消息可能不同 由于消息过期而最初交付的那些 以及更高优先级消息的到达。

      【讨论】:

      • 为了让它工作,我需要关闭我的消费者,直到我知道故障已经结束。我需要保证消息顺序。我什么时候知道打电话恢复?我需要等到成功处理的新消息通过。在这种情况下,我会在调用recover 处理之前的消息之前处理一条新消息。
      • 我不确定您的消费者在发生故障时如何没有停止,因为当 tcp 连接断开时您的连接无效。失败后重新连接时,调用recover。
      • 我与 JMS 的连接不是失败的原因。这是我与数据库的连接。因此,当我使用一条消息时,我会尝试将其中的数据放入数据库中。这会引发异常。在数据库备份之前,所有消息都会发生这种情况。所以我不会在这段时间阻止我的消费者。我发现我的数据库连接已备份的唯一方法是,如果我使用一条消息并且未能抛出异常。
      • 这不是未确认消息的情况,而是错误确认消息的处理。客户端确认了第 5 条消息,但 1-4 条消息也按照规范得到了确认,但是这 4 条消息的处理可能处于部分状态。
      猜你喜欢
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 2012-11-26
      • 2013-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多