【问题标题】:Spring AMQP - return the message back to the beginning of the queueSpring AMQP - 将消息返回到队列的开头
【发布时间】:2019-07-01 22:19:07
【问题描述】:

我想知道是否有任何方法可以将消息返回到队列中的原始位置。例如,假设我们有这样的顺序:

A-B-C-D A 是头部,D 是尾部。通常,当我们使用nackrejectrequeue=true 时,它只是将消息排入当前尾部之后。在这种情况下,当A 重新排队时,新的排序变为B-C-D-A。但是,我想知道是否有任何方法可以排入队列的开头。因此,如果 A 被“送回”,它将被放置在队列的开头,在它原来的位置。

我使用 Spring AMQP 搜索解决方案。

【问题讨论】:

  • 这不是 AMQP 队列的工作方式。为什么需要这种行为?
  • 我知道这不是他们的自然行为方式。我想这样做的原因是我需要在处理消息时遵循严格的顺序。例如,“follow X”和“unfollow X”消息应该按照它们发送的方式进行处理。我不想先处理“取消关注”。因此,假设在处理消息时数据库关闭,我通常发送nackrejectrequeue=true,这会破坏订单。我可以自己解决这个问题。但我一直在寻找开箱即用的 Spring 或 Rabbit 可能支持的东西。希望这是有道理的。
  • 如果没有看到对应的follow消息,消费者应该nackunfollow消息。这将恢复自然秩序。
  • 这需要数据库检查。例如,如果followunfollow 已在非常短的时间间隔内发送,那么您的建议可能有效。但是如果这两个之间有一个月。不会有任何对应的follow,我们必须检查数据库。顺便说一下,Follow/unfollow 只是一个例子。案例可能更复杂。

标签: java rabbitmq spring-amqp spring-rabbit


【解决方案1】:

您需要将预取(qos)设置为1。否则任何预取的消息都会在A重新投递之前被投递。

但是,它会影响性能。

【讨论】:

  • 可以肯定的是,您是在说 ListenerContainer 中的 setPrefetchCount 吗?我的意思是,我应该用它来设置预取计数吗?因为如果是的话,我已经这样做了。问题是当我取消消息时,由于数据库不可用,它会将消息重新排队到队列的末尾。我希望它返回它所属的任何地方,队列的头。希望我没有误解您的解决方案。
  • 只要prefetchCount为1,就会到队列头部,立即重新投递。如果预取计数>1,在requeued之前会得到其他预取的消息一。很久以前(很多年)RabbitMQ 曾经在尾部而不是头部重新排队,但现在改为在头部重新排队。
  • 不知道。谢谢@加里·拉塞尔。一个问题。所以prefetchCount=1,我们nack 消息并重新排队,它将被重新传递。这是否意味着,如果我们总是发送nack,它可能会陷入循环?
  • 是的,当然。如果消息具有唯一的 messageId 属性,您可以使用有状态重试拦截器并在重试次数后放弃。请参阅参考手册。
  • 它处于manual 确认模式,据我所知,重试拦截器仅在auto 模式下工作。另外,如果可能的话,您能否参考任何关于此的来源:RabbitMQ used to requeue at the tail instead of the head but it was changed to requeue at the head?不幸的是,我找不到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
相关资源
最近更新 更多