I'm implementing two services: A and B. I'm trying to implement a syncronous communication (Remote Procedure Call, or RPC) between A and B.
Very simple. A needs a information from B, so A send a message and wait for a reply from B. A can't continue without this information
I'm using the method rabbitTemplate.convertSendAndReceive
from Spring RabbitMQ. This works as expected if the B is running. My code is very similar from this link.
If B is not running, A waits for a little time (few seconds) and receive as reply a null
. In this case, I was expectating some exception saying that there is no consumer available.
The documentation says:
By default, the send and receive methods will timeout after 5 seconds and return null. This can be modified by setting the replyTimeout property. Starting with version 1.5, if you set the mandatory property to true (or the mandatory-expression evaluates to true for a particular message), if the message cannot be delivered to a queue an AmqpMessageReturnedException will be thrown. This exception has returnedMessage, replyCode, replyText properties, as well as the exchange and routingKey used for the send.
I tried to set:
rabbitTemplate.setMandatory(true);
But any exception is throwed. I think because the queue is still alive in RabbitMQ, because there is some messages sent from A when B are out and they are waiting for to processed by B.
So, the null
return is how I know that there is no consumer?
Another problem in this case: the message sent from A will be waiting in the queue until B consumes. But as I'm implementing a syncronous communication, this behaviour not make any sense if B is not running, because when B starts again it will consume and process without return the information to A. This will be a "lost" processing. Is this normal with RabbitMQ RPC communication?
I'm using Spring Boot 1.5.9 and the dependency spring-cloud-starter-stream-rabbit
Mandatory has nothing to with consumers; it's to ensure the message was delivered to a queue.
Yes, getting null
is an indication that the operation timed out (5 seconds by default).
You can configure the queue with a time to live (ttl) so stale messages will be removed from the queue if they are not processed within that time.