【问题标题】:Should exchange or queue be declared multiple times in RabbitMQ?是否应该在 RabbitMQ 中多次声明交换或队列?
【发布时间】:2015-07-21 03:06:42
【问题描述】:

我在Server AServer B之间与我的同事讨论RabbitMQ的设计,流程图如下。

Server AServer Bexchange AQueue B 发送消息,并从Server BQueue A 接收消息。 Server B 反之亦然。

Server A 中有两个类,用C++ 实现;一个是sender,另一个是receiver。与JavaScript 实现的Server B 的代码结构相同。

对于Server A 中的senderreceiver。我同事的想法是:

  • Sender 中的初始化:
    • 创建与rabbitmq的连接
    • 声明exchange A
    • 声明Queue B
    • 将密钥绑定到Queue B
  • Receiver 中的初始化:
    • 创建与rabbitmq的连接
    • 声明exchange B
    • 声明Queue A
    • 将密钥绑定到Queue A

Server B 中的逻辑相同。

但是,我不认为Queue BExchange B 应该在Server A 中声明。它们应该在Server B 中声明。

最后,我按照我同事的想法来实现它,因为他之前做过一些相关的工作。


今天测试过程中Sender模块amqp_queue_declare函数Server A,但重启RabbitMQ后运行良好。所以我怀疑我的同事对Sender的初始化的想法。

我的想法:

  • Server A
    • Sender 中的初始化
      • 创建与rabbitmq 的连接
      • 声明Exchange A
    • Receiver 中的初始化
      • 创建与rabbitmq的连接
      • 创建Queue A
      • 将密钥绑定到Queue A
  • Server B
    • Sender 中的初始化
      • 创建与rabbitmq的连接
      • 声明Exchange B
    • Receiver 中的初始化
      • 创建与rabbitmq的连接
      • 创建Queue B
      • 将密钥绑定到Queue B

有人能告诉我我的想法有什么问题吗?还是有更好的解决方案?


编辑:回答来自@Sigismondo 的问题

  • 是否所有消息都需要传递给消费者 A/B?

    没有

  • 如果某些消息丢失,是否需要通知消费者 A/B?

    没有。我想知道消费者 A 怎么知道有消息丢失?

  • 如果无法访问消费者 A/B,预期的行为是什么?

    如果消费者 A 不可达,则生产者 B 不会向 A 发送任何消息,反之亦然。 B 怎么知道消费者 A 不可到达?

    目前,在我的系统中,每条消息都有 ack。所以B在前一种情况下没有得到A的ack,那么B不会向A发送消息。

  • 如果生产者 A/B 出现故障,预期的行为是什么?

    如果生产者 B 宕机,那么 A 将不会收到来自 B 的任何消息。因此 A 不会向 B 发送任何消息。

【问题讨论】:

  • “目前,在我的系统中,每条消息都有 ack”。你的意思是 RabbitMQ/AMQP 标准 ack,不是吗?
  • @Sigismondo 不是 amqp 标准的 ack,是我自己系统中定义的 ack 消息。
  • 我明白了。您的问题不能归类为“RPC-over-messaging”吗,例如此处所示? rabbitmq.com/tutorials/tutorial-six-python.html
  • 是的,RPC也在我的系统中使用
  • 据我猜测,在我看来,您希望将生产者和消费者耦合起来,而消息传递的目的恰恰相反:将生产者和消费者解耦。因此,即使消费者不在那里,您也可以让请求放在请求队列中,即使消费者在那里(原始请求者),它也可以消费它并将响应放在响应队列中

标签: rabbitmq message-queue amqp


【解决方案1】:

两个服务器都声明队列和交换器是完全合法的,这通常是处理命名队列时的首选方法:通常您希望生产者和消费者解耦,并让两者都声明 (即:如果缺少则创建)队列和交换,您可以让两者正常工作,并且您可以保证不会丢失任何消息,以防其他对等方尚未启动,即使在 RabbitMQ 全新安装上也是如此。

特别重要的是:

  • 消费者声明必须从中消费消息的队列(否则它将无法消费它们)。

  • 生产者声明队列在生成消息之前生成它的交换(否则它们将丢失,以防没有消费者创建队列)。

这是使用命名队列时使用的典型方法,这似乎是您在这里所做的。

现在,如果您希望在消费者不在的情况下忘记消息,那么生产者将不会声明任何队列:消费者可以创建一个temporary queue 并将其绑定到交换器。

最后,如果是这种情况,并且您希望在没有消费者(并且没有绑定到交换的队列)的情况下得到通知,您可以使用alternate exchanges

所以,您看到了:您可以使用一些选项,但每个选项都有一个基本原理:您必须根据具体问题选择要使用的选项 - 您的解释还不够充分:即使非常详细,它也缺少某些方面:

  • 是否所有消息都需要传递给消费者 A/B?
  • 如果某些消息丢失,是否需要通知消费者 A/B?
  • 如果无法访问消费者 A/B,预期的行为是什么?
  • 如果生产者 A/B 出现故障,预期的行为是什么?

但是,amqp_queue_declare 根本不应该挂起:如果是这种情况,您正面临一个错误,或者我不知道是什么,但据我所知,这不是它的预期行为。

【讨论】:

  • 感谢您的回答,我已经在我的问题中回答了您的问题
猜你喜欢
  • 2016-05-28
  • 1970-01-01
  • 2015-06-06
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-08
相关资源
最近更新 更多