2013-03-08 230 views
6

保持持久队列及其绑定但挂起其消费者的最佳方式是什么?RabbitMQ挂起队列消耗

用例如下:我想“让它崩溃”并停止处理消息,如果我们收到一堆我们无法处理的消息(例如数据库关闭或架构问题),但希望不断聚合队列。这是允许发布但暂停使用。

我能想到的三种解决方案:

  1. 我可以绑定到队列中的所有消费者不断拒绝消息,并重新排队,但这是有点浪费资源,更何况我已经编程做以上逻辑。
  2. 我可以打电话给basic.cancelConsumer上的所有消费者(见下文)的
  3. 还是在方面,我想我可以对所有绑定到队列中的SimpleMessageListenerContainersshutdown

#1我们已经在做,因为邮件正在被拒绝。问题是这最终会像一个无限的循环失败,如果你的日志记录失败,甚至更多的资源被浪费了。

#3似乎是理想的,但我必须知道一些如何知道所有的消息监听器,然后通知他们关机。我想我可以使用扇出交换来通知队列需要暂停。我觉得RabbitMQ必须为这个逻辑内置一些东西。另一个问题是您可以将多个队列绑定到消息容器(并非所有队列都可能需要暂停)。

对于#2我知道我可以cancel the consumerconsumerTag但问题(假设是上面做正确的方式)是我在哪里得到的consumerTag是清单到一个队列?

回答

1

如果你需要停止一个消费者,那么只需调用基本的取消,这是做到这一点的方法。

拥有持久队列是您在申报队列时解决的问题:durable=trueauto_delete=false

具有持久性消息是,当你把它们发布决定:delivery_mode=2.

每个消费者都有自己的消费标签。无论何时当您将消息从队列中取出时,信封都应该有消费者标签,您应该使用该标签调用基本取消。 AFAIK,你不能在conn 1中拥有消费者A,并且在不同的连接上为该消费者调用基本的取消。我可能在这个错误。

+0

谢谢。我知道如何在上面声明像兔子一样的队列。看起来我必须自己管理我的消费者,这是我已经走下的路。如果兔子有明智的选择来暂停队列的使用,那将会很好。 – 2013-03-08 19:11:27

+0

你可以从连接做的唯一的事情是强制关闭它从管理员这不是你正在寻找 – 2013-03-08 20:48:50

1

此解决方案是具体。它的基本#3从我的答案。

我维护的队列名称为Map<String,CustomSimpleMessageListenerContainer>的服务定制扩展为SimpleMessageListenerContainer

经过一定数量的例外之后,我发送一个“恐慌”消息,该消息进入服务收到的特殊队列以关闭消费者。