Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should exchange or queue be declared multiple times in RabbitMQ?

I discuss the RabbitMQ design with my colleague between Server A and Server B, here is the flow chart as following.

enter image description here

Server A sends messages to Server B through exchange A and Queue B, and receives messages from Server B through Queue A. vice versa for Server B.

There are two classes in Server A implemented with C++; one is sender, the other is receiver. The same code structure is for Server B implemented with JavaScript.

For the sender and receiver in Server A. My colleague's idea is:

  • The initialization in Sender:
    • create connection with rabbitmq
    • declare the exchange A
    • declare the Queue B
    • bind the key to Queue B
  • The initialization in Receiver:
    • create connection with rabbitmq
    • declare the exchange B
    • declare the Queue A
    • bind the key to Queue A

The same logic in Server B.

However, I do NOT think Queue B and Exchange B should be declared in Server A. They are should be declared in Server B.

Finally, I implement it following my colleague's idea, due to he has done some related work before.


Today, the Server A hang at the function amqp_queue_declare in Sender module during test, but it works well after restarting RabbitMQ. So I doubt the my colleague's idea for the initialization of Sender.

My thought:

  • Server A
    • The initialization in Sender
      • create connection with rabbitmq
      • declare the Exchange A
    • The initialization in Receiver
      • create connection with rabbitmq
      • create the Queue A
      • bind the key to Queue A
  • Server B
    • The initialization in Sender
      • create connection with rabbitmq
      • declare the Exchange B
    • The initialization in Receiver
      • create connection with rabbitmq
      • create the Queue B
      • bind the key to Queue B

Could someone tell me is there anything wrong with my thought? or is there better solution?


Edit: answer questions from @Sigismondo

  • do all the messages need to be delivered to the consumer A/B?

    No

  • does the consumer A/B need to be notified in case some messages are lost?

    No. I want to know how could consumer A know there is message lost?

  • what is the intended behavior in case the consumer A/B is not reachable?

    If consumer A is not reachable, then producer B will not sent any message to A, and vise versa. How could B know the consumer A is not reachable??

    Currently, in my system, there is ack for every message. so B does not get ack from A in the previous case, then B will not sent message to A.

  • what is the intended behavior in case the producer A/B is down?

    If producer B is down, then A will not receive any message from B. So A will not send any message to B.

like image 281
zangw Avatar asked Jul 21 '15 03:07

zangw


1 Answers

It's perfectly legit that both servers declare the queue and the exchange, and it's usually the preferred approach, when dealing with named queues: usually you want producers and consumers be decoupled, and letting both declare (i.e.: create if missing) the queues and the exchange, you let both work correctly and you have the guarantee that no messages are lost, in case the other peer has not been started yet, even on a RabbitMQ fresh install.

In particular it's important that:

  • the consumer declare the queues from which must consume messages (or it won't be able to consume from them).

  • the producer declare the queues and the exchanges to which it produces before producing messages (or they will be lost, in case no consumer has created the queues).

This is the typical approach used when using named queues, that seems what you are doing here.

Now, in case you want the messages to be forgotten in case the consumer is not there, than the producer won't declare any queue: the consumer can create a temporary queue and bind it to the exchange.

Finally, if this is the case, and you want to be notified in case there are not consumers (and no queues bound to the exchange), you can use alternate exchanges.

So, you see it: there are some options that you can use, but there is a rationale for each one: you must choose which one to use based on the specific problem - and that has not been qualified enough by your explanation: even if very detailed it's missing some aspects:

  • do all the messages need to be delivered to the consumer A/B?
  • does the consumer A/B need to be notified in case some messages are lost?
  • what is the intended behavior in case the consumer A/B is not reachable?
  • what is the intended behavior in case the producer A/B is down?

However amqp_queue_declare should not hang at all: if this is the case you are facing a bug or I have no idea what, but that's not the intended behavior for it, to my knowledge.

like image 72
Sigi Avatar answered Oct 03 '22 22:10

Sigi