首页 文章

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

提问于
浏览
1

我是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 回答

  • 4

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

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

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

  • 0

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

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

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

    • 需要使用不同的路由密钥来绑定队列,或者

    • 需要使用不同的交换

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

    这种情况将允许消费者A1或消费者A2处理有问题的消息,但这样做是让他们都订阅同一个队列 .

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

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

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

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

相关问题