RabbitMQ-为什么错误的订户会收到已发布的消息?

时间:2018-10-23 06:51:50

标签: rabbitmq message-queue amqp

我有两项服务,经理收藏家

  1. 管理器已通过routingKey COLLECTED_USER订阅了队列user.collected,并调用了UserCollected处理程序。
  2. 收集器已使用routingKey COLLECT_USER订阅了队列user.collect,并调用了CollectUser处理程序。

可以有多个收集器,因此我将exclusive设置为false(有关代码,请参见下文)。

还有其他服务可以监听事件,例如

  • user.created
  • user.updated
  • user.deleted

此外,还有一些服务可以监听更多常规事件,例如

  • #.created
  • user.#

以此类推。

所以我正在使用topic交换。

设置

| exchange | type  | routingKey     | queueName      |
| -------- | ----- | -------------- | -------------  |
| MY_APP   | topic | user.collect   | COLLECT_USER   |
| MY_APP   | topic | user.collected | COLLECTED_USER |

会发生什么:

  1. 管理器发布具有routingKey user.collect
  2. 的消息
  3. 收集器获得user.collect消息并调用CollectUser处理程序
  4. 收集器的 CollectUser处理程序确实起作用,然后发布带有routingKey user.collected的消息
  5. 经理获得user.collected消息并调用UserCollected处理程序

实际发生的事情:

  1. 管理器发布带有routingKey user.collect(正确)的消息
  2. 收集器获取user.collect消息并调用CollectUser处理程序(正确)
  3. 管理器也会获取user.collect消息,并使用错误的数据调用UserCollected处理程序。 (错误)
  4. 收集器的 CollectUser处理程序确实起作用,然后发布带有routingKey user.collected(正确)的消息
  5. 管理器获取user.collected消息并调用UserCollected处理程序(正确)

我的问题

管理器为什么会收到user.collect消息,原因是:

  1. 它在COLLECTED_USER队列而不是COLLECT_USER队列上监听,并且
  2. 正在监听COLLECT_USER队列的 Collector 已经处理了该消息。

实施细节

我按如下方式创建订阅者和发布者(针对相关性进行了修剪)

创建订户

使用AMQP url和参数urlexchangetyperoutingKeyqueueNamehandler

const connection = await amqp.connect(url)
const channel = await connection.createChannel()
channel.assertExchange(exchange, type, { durable: true })
const result = await channel.assertQueue(queueName, { exclusive: false })
channel.bindQueue(result.queue, exchange, routingKey)
channel.prefetch(1)
channel.consume(result.queue, handler)

创建发布者

根据AMQP url和参数urlexchangetype

const connection = await amqp.connect(url)
const channel = await connection.createChannel()
await channel.assertExchange(exchange, type, { durable: true })

发布

给定channel和参数exchangeroutingKeymessage

await channel.publish(exchange, routingKey, message)

注意

此问题是RabbitMQ — Why are my Routing Keys being ignored when using topic exchange 的后续问题。

1 个答案:

答案 0 :(得分:1)

我终于弄清楚了我的问题所在。肮脏的交流。在尝试此操作时,我无意中添加了一个交换,该交换将消息路由到错误的队列,这引起了我的困惑。

要解决此问题,我启动了RabbitMQ管理员GUI并删除了所有队列,然后让我的代码创建所需的队列。上面列出的代码没有问题。