Search code examples
javaspringrabbitmqspring-rabbit

Using RabbitMQ RPC doesn't fail when there is no consumer. Is this the expected behaviour?


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.

Scenario

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

The question

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


Solution

  • 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.