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

zan*_*ngw 5 message-queue amqp rabbitmq

我讨论了RabbitMQ设计与我之间的同事Server AServer B,这里是流程图如下.

在此输入图像描述

Server A将消息发送到Server B通过exchange AQueue B,以及从接收消息Server B通过Queue A.反之亦然Server B.

Server A实现了两个类C++; 一个是sender,另一个是receiver.相同的代码结构用于Server B实现JavaScript.

对于senderreceiverServer A.我的同事的想法是:

  • 发件人中的初始化:
    • 创建连接 rabbitmq
    • 宣布 exchange A
    • 宣布 Queue B
    • 将密钥绑定到 Queue B
  • Receiver中的初始化:
    • 创建连接 rabbitmq
    • 宣布 exchange B
    • 宣布 Queue A
    • 将密钥绑定到 Queue A

同样的逻辑Server B.

但是,我不认为Queue BExchange B应该申报Server A.他们应该在宣布Server B.

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


今天,Server A 在函数amqp_queue_declareSender测试过程中的模块,但它重启后运行良好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不可达?

    目前,在我的系统中,每条消息都有一个确认.所以B在前一种情况下没有从A获得确认,那么B将不会向A发送消息.

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

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

Sig*_*ndo 6

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

特别重要的是:

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

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

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

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

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

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

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

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