【问题标题】:Do i require a queue for each consumer in rabbitMQ?rabbitMQ 中的每个消费者都需要一个队列吗?
【发布时间】:2020-04-03 21:04:06
【问题描述】:

我有下一个问题,我有三个程序,它们应该在修改数据库时向 rabbitMQ 发送通知(消息),每个程序也应该收到该通知,以便他们知道对数据库的修改。

我是使用rabbitMQ的新手,所以我不知道工作方式,我有点理解官方页面上的“hello world”教程,当我尝试与多个消费者一起使用它(一个队列)时,只有一个他们中的一些人收到了通知,所以我猜我需要为每个消费者使用一个队列,但我想知道在这种情况下这是否是使用 rabbitMQ 的正确方法。

作为关于我的项目的额外信息,我需要每个消费者接收发送的最后一条消息,他们不应该关心过去的消息,所以如果消费者在开始工作时不可用,它不应该收到所有过去的垃圾邮件通知。

【问题讨论】:

  • 听起来你可能已经实现了work queue,其中每条消息只发送给一个消费者。但是您可能想要publish-and-subscribe。请参阅 this page 了解概述,包括更灵活的变体,例如主题。
  • 发布和订阅是我需要的,谢谢

标签: rabbitmq


【解决方案1】:

是的,您确实需要为每个消费者排队。

你可以使用扇出交换

channel.ExchangeDeclare("database", ExchangeType.Fanout);

关于您的“额外信息”

作为关于我的项目的额外信息,我需要每个消费者接收发送的最后一条消息,他们不应该关心过去的消息,所以如果消费者在开始工作时不可用,它不应该收到所有过去的垃圾邮件通知。

您可以按照官方教程on this page 中的建议使用非持久的、独占的、自动删除的“临时队列”

channel.QueueDeclare();

以下是本页的两句话:

  1. ...我们也只对当前流动的消息感兴趣,而不是旧消息。

  2. ... 每当我们连接到 Rabbit 时,我们都需要一个新的空队列。为此,我们可以创建一个具有随机名称的队列,或者更好的是 - 让服务器为我们选择一个随机队列名称。

然后最后将队列绑定到exchange:

channel.QueueBind(queue: queueName, exchange: "database", routingKey: "");

大家一起:

channel.ExchangeDeclare("database", ExchangeType.Fanout);
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName,
                  exchange: "database",
                  routingKey: "");

当然,每个程序都会有发布者逻辑和订阅者逻辑。 如果我们将这3个程序分别命名为“A”、“B”和“C”,然后使用在线模拟器工具http://tryrabbitmq.com/,我们得到以下

==============

提示

将来您可能希望区分不同类型的数据库更改(例如架构更改、数据更改) 为此,我将使用每个通知类型的“数据库”主题交换和路由键。 其余的将保持不变:

channel.ExchangeDeclare("database", ExchangeType.Topic);
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName,
                  exchange: "database",
                  routingKey: "schema.changed");

【讨论】:

  • 真正完整的答案,已经测试过代码并且看起来不错,感谢您让我理解。
猜你喜欢
  • 2017-04-13
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多