当前位置: 首页 > 知识库问答 >
问题:

在ActiveMQ Artemis 2.11.0中,从队列重新传递是无序的

鲁熙云
2023-03-14

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

例如:

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

重新交付阶段的推送

redelivery-delay0时,一切都没问题,但是用户端的重新交付频率太高了。我的期望是,在未确认的消息从队列中清除或确认之前,应该停止向使用者的每一次传递。我们正在使用一个队列来连接单个设备。每个设备都有自己的I/O队列,只有一个消费者。队列这个词对我来说意味着严格的排序。可以像“strict_redelivery_order”一样对此行为进行可配置。

共有1个答案

蒯硕
2023-03-14

你看到的是预期的行为。如果使用redelivery-delay>0,则传递顺序将被破坏。如果使用0redelivery-delay,则传递顺序不会中断。因此,如果要保持严格的顺序,那么使用0redelivery-delay

如果代理在重新传递延迟期间阻止队列上所有其他消息的传递,这将完全破坏消息吞吐量性能。如果重新交付的延迟是60秒或10分钟呢?队列将一直被阻塞。对于为数百或数千个客户机服务的enterprise message broker来说,这是站不住脚的,每个客户机都可能定期在共享队列上触发重新传递。此行为不可配置。

如果您绝对必须维护消息顺序,即使是对于不能立即使用的消息,并且0redelivery-delay导致重新传递太快,那么我看到以下几个可能的选项(没有特定的顺序):

  • 配置死信地址,并将max-delivery-attems设置为适当的值,以便在几次重新传递后,可以从队列中清除有问题的邮件。
  • 在客户端中实现您自己的延迟。这可以简单到捕捉任何异常,并在调用ctx.rollback().
  • 之前使用 thread.sleep()
 类似资料:
  • 我正在尝试设置一个jms队列,并在事务失败时进行重新交付。出现的情况是,一条消息被多次重新传递(和处理),因为在消息处理代码之后,会话会关闭两次。第二次关闭尝试抛出错误,因为它已经关闭,所以事务被回滚,消息被重新传递。 以下是我的配置: } 和 } 怎么了?上面提到的错误是:ExceptionApperstandardImpl:hh000346:托管刷新期间出错[会话/实体管理器关闭]

  • 我正在读一条来自Solace的信息。我能够成功地阅读信息。假设我正在阅读一条消息,在侦听器线程上读取/处理消息时,应用程序崩溃。那我怎么能在那上面再读一遍那条信息呢。使用下面的代码,我无法再次阅读该消息。下面是我的配置

  • 我正在为Kafka工作客户:librdkafka。图书馆在这里https://github.com/edenhill/librdkafka/blob/master/examples/rdkafka_example.cpp.我的程序正在向代理写入2000000条消息。在此过程中,我重新启动了代理。有时,没有消息无法传递到代理。有时,大约100000条消息未能传递到代理。队列缓冲。最大消息数=1000

  • 我的骆驼上下文文件如下所示: 我在应用程序中的各种不同endpoint之间有几条其他路由,它们需要重新传递配置,并且按照预期的方式运行。但是,这个特定的路由类型(从文件到队列)似乎并不遵循我配置的任何重新传递策略。当我关闭ActiveMQ代理时,路由会尝试每6秒重新传递一次文件。: 10:54:17,088 WARN c_demo%5GenericFileOnCompletion 105-org.

  • 我有一个使用Spring和RabbitMQ的项目设置。目前,我的应用程序可能会收到一条amqp消息,在另一个异步进程完成之前无法处理该消息(遗留和完全分离,我无法控制)。因此,结果是我可能不得不等待处理消息一段时间。其结果是变压器出现异常。 当消息被NACK回rabbitMQ时,它会将其放回队列的头部,并立即重新拉入队列。如果我收到的无法处理的消息等于并发侦听器的数量,我的工作流就会被锁定。它转动