I discuss the RabbitMQ
design with my colleague between Server A
and Server B
, here is the flow chart as following.
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:
rabbitmq
exchange A
Queue B
Queue B
rabbitmq
exchange B
Queue A
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
rabbitmq
Exchange A
rabbitmq
Queue A
Queue A
Server B
rabbitmq
Exchange B
rabbitmq
Queue B
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.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With