【问题标题】:Redelivery from queue is unordered in ActiveMQ Artemis在 ActiveMQ Artemis 中,从队列中重新传递是无序的
【发布时间】:2020-02-20 11:26:56
【问题描述】:

如果 ActiveMQ Artemis 配置了 redelivery-delay > 0 并且 JMS 侦听器使用 ctx.rollback() 或 ctx.recover() 则代理将按预期重新传递消息。但是,如果生产者在重新传递期间将消息推送到队列,那么接收者会收到无序的消息。

例如:

队列:1 -> 消息 1 按预期重新传递

在重新交付阶段推送

队列:2,3 -> 接收者得到 2,3,1

redelivery-delay 和 0 一切正常,但消费者方面的重新交付频率太高。我的期望是,在未确认的消息从队列中清除或确认之前,应该停止向消费者的每次传递。我们正在使用队列来连接单个设备。每个设备都有自己的 I/O 队列,只有一个消费者。 queue 这个词对我来说意味着严格的排序。让这种行为像“strict_redelivery_order”一样可配置可能会很好。

【问题讨论】:

  • 创建一个重新发送延迟为 1 毫秒的代理配置。推送消息,然后将其回滚。在此之后,阿尔忒弥斯将消息重新渲染为加速。每 1 毫秒。现在推送第二个消息。这将立即交付。我的期望是,每次向消费者的交付都应该停止,直到未确认的消息被清除或从队列中确认
  • 我同意一般用途。但是我们使用队列来连接单个设备。每个设备都有自己的 I/O 队列,只有一个负责的消费者。单词队列建议我严格排序。让这种行为像“strict_redelivery_order”这样可配置会很好

标签: activemq-artemis


【解决方案1】:

您看到的是预期的行为。如果您使用redelivery-delay > 0,那么交货单将被破坏。如果您使用redelivery-delay 或0,则不会破坏交货单。因此,如果您想保持严格的秩序,请使用 redelivery-delay 或 0。

如果代理在重新传递延迟期间阻止了队列中所有其他消息的传递,这将完全破坏消息吞吐量性能。如果重新投递延迟是 60 秒或 10 分钟怎么办?队列将一直被阻塞。对于为数百甚至数千个客户端提供服务的企业消息代理来说,这将是站不住脚的,每个客户端可能会定期触发共享队列上的重新传递。此行为不可配置。

如果您绝对必须保持消息顺序,即使是对于无法立即使用的消息,并且 redelivery-delay 或 0 会导致重新传递太快,那么我看到了一些潜在的选项(无特定顺序):

  • 配置dead-letter address 并将max-delivery-attempts 设置为合适的值,以便在几次重新传递后,可以从队列中清除有问题的消息。
  • 在您的客户端中实施您自己的延迟。这可以像捕获任何异常并在调用ctx.rollback() 之前使用Thread.sleep() 一样简单。

【讨论】:

  • 我就是这么做的。我将 redellivery 延迟设置为 0 并在消费者端等待。
  • 一般来说,“问题”发生在重新发送尝试大于 0 毫秒时。
  • 重新交付延迟为 0 时一切正常。但是消费者方面的频率很高?‍?。
  • 我从您的 cmets 收集了所有信息并将它们添加到您的问题中,以便一切都更加清楚。然后,除了一些建议之外,我还使用我的 cmets 的详细信息更新了我的答案。
猜你喜欢
  • 2019-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-16
  • 1970-01-01
相关资源
最近更新 更多