应该在RabbitMQ中多次声明交换或队列吗?

时间:2015-07-21 03:06:43

标签: rabbitmq message-queue amqp

我与RabbitMQServer A之间的同事讨论Server B设计,以下是流程图。

enter image description here

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

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

对于sender中的receiverServer A。我的同事的想法是:

  • 发件人中的初始化:
    • rabbitmq
    • 建立联系
    • 声明exchange A
    • 声明Queue B
    • 将密钥绑定到Queue B
  • Receiver中的初始化:
    • rabbitmq
    • 建立联系
    • 声明exchange B
    • 声明Queue A
    • 将密钥绑定到Queue A

Server B中的相同逻辑。

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

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

今天,测试期间Server A模块中的amqp_queue_declare函数Sender 挂起,但重启RabbitMQ后效果很好。所以我怀疑我的同事关于Sender初始化的想法。

我的想法:

  • Server A
    • 发件人中的初始化
      • rabbitmq
      • 建立联系
      • 声明Exchange A
    • Receiver中的初始化
      • rabbitmq
      • 建立联系
      • 创建Queue A
      • 将密钥绑定到Queue A
  • Server B
    • 发件人中的初始化
      • rabbitmq
      • 建立联系
      • 声明Exchange B
    • Receiver中的初始化
      • rabbitmq
      • 建立联系
      • 创建Queue B
      • 将密钥绑定到Queue B

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

修改:回答来自@Sigismondo的问题

  • 是否需要将所有邮件传递给消费者A / B?

    没有

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

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

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

    如果无法访问消费者A,则生产者B不会向A发送任何消息,反之亦然。 B如何知道消费者A无法访问?

    目前,在我的系统中,每条消息都有一个确认消息。因此B在前一种情况下不会从A获得确认,然后B不会向A发送消息。

  • 生产者A / B关闭时的预期行为是什么?

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

1 个答案:

答案 0 :(得分:6)

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

特别重要的是:

  • 使用者声明必须使用消息的队列(或者它将无法使用消息)。

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

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

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

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

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

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

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