在RabbiqMQ Direct交换中仅向绑定到路由密钥的一个队列发送消息

时间:2016-03-24 21:13:35

标签: rabbitmq

我是RabbitMQ的新手,这让我很困惑。我已经设置了直接交换,不同的队列在此交换机上订阅了不同的路由密钥。我想要的是,如果使用一个路由密钥发布消息,则无论订阅该路由密钥的队列数是多少,它都只从一个订户消费。

当前情况:

交换(类型:直接)

-QueueA1  (receives message A from exchange with routing key of "TypeA")
-QueueA2  (also receive message A from exchange with routing key of "TypeA")
-QueueB  (doesn't receive message A because it subscribes to key "TypeB")

所需:

-QueueA1  (receives message A from exchange with routing key of "TypeA")
-QueueA2  (doesn't receive message A because it's already consumed by QueueA1)
-QueueB  (doesn't receive message A because it subscribes to key "TypeB")

我需要使用其他交换吗?我如何实现预期的方案?

2 个答案:

答案 0 :(得分:4)

您可以使用单个QueueA并订阅此队列的多个消费者来实现您的目标:

Direct exchange
|
|-- ["TypeA"]--> QueueA
|                |-- Consumer A1
|                `-- Consumer A2
|
`-- ["TypeB"]--> QueueB

在这种情况下,在QueueA上排队的邮件将仅传递给一个使用者。然而,获取消息的消费者是未定义的:它们是以循环方式选择的。

答案 1 :(得分:0)

w / RabbitMQ,在给定交换中匹配的所有路由密钥都将具有传递到指定队列的消息副本。

因此,在您的方案中,您将始终让QueueA1和QueueA2接收TypeA的消息。这是路由键的工作方式。没有办法解决这个问题,使用一次交换。

如果您需要QueueA1和QueueA2来接收不同的消息,那么您可以:

  • 需要使用不同的路由键来绑定队列,或
  • 需要使用不同的交换

关于Jean-Sebastient的建议......

此方案将允许Consumer A1 Consumer A2处理有问题的消息,但这样做会让他们同时订阅同一个队列。

如果您正在尝试确保有一个消费者接收到该消息,那么这就是您想要做的。但是,如果您需要两个队列并且需要确保只有一个队列收到消息,那么您需要使用我建议的其他选项之一。

最后,如果您正在考虑保证邮件只处理一次,则这些选项都不会这样做。

从表面上看,它看起来大部分时间都有效。但是会出现出现问题的情况,并且您将有多个队列或消费者处理相同的消息。

要处理这种情况,您需要查看"幂等"在你的消息处理中。这通常是用数据库和ID来处理的,它已经被处理过了,但还有其他解决方案。