0

Let me start by describing the system. There are 2 applications, let's call them Client and Server. There are also 2 queues, request queue and reply queue. The Client publishes to the request queue, and the server listens for that request to process it. After the Server processes the message, it publishes it to the reply queue, which the Client is subscribed to. The Server application always publishes the reply to the predefined reply queue, not a queue that the Client application determines.

I cannot make updates to the Server application. I can only update the Client application. The queues are created and managed by the Server application.

I am trying to implement request/reply pattern from Client, such that the reply from the Server is synchronously returned. I am aware of the "sendAndReceive" approach with spring, and how it works with a temporary queue for reply purposes, and also with a fixed reply queue.

Spring AMQP - 3.1.9 Request/Reply Messaging

Here are the questions I have:

  1. Can I utilize this approach with existing queues, which are managed and created by the Server application? If yes, please elaborate.
  2. If my Client application is a scaled app (multiple instances of it are running at the same time), then how do I also implement it in such a way, that the wrong instance (one in which the request did not originate) does not read the reply from the queue?
  3. Am I able to use the "Default" exchange to my advantage here, in addition to a routing key?

Thanks for your time and your responses.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
Brian
  • 168
  • 1
  • 6

1 Answers1

0
  1. Yes; simply use a Reply Listener Container wired into the RabbitTemplate.

IMPORTANT: the server must echo the correlationId message property set by the client, so that the reply can be correlated to the request in the client.

  1. You can't. Unlike JMS, RabbitMQ has no notion of message selection; each consumer (in this case, reply container) needs its own queue. Otherwise, the instances will get random replies and it is possible (highly likely) that the reply will go to the wrong instance.

...it publishes it to the reply queue...

With RabbitMQ, publishers don't publish to queues, they publish to exchanges with a routing key. It is bad practice to tightly couple publishers to queues. If you can't change the server to publish the reply to an exchange, with a routing key that contains something from the request message (or use the replyTo property), you are out of luck.

  1. Using the default exchange encourages the bad practice I mentioned in 2 (tightly coupling producers to queues). So, no, it doesn't help.

EDIT

If there's something in the reply that allows you to correlate it to a request; one possibility would be to add a delegating consumer on the server's reply queue. Receive the reply, perform the correlation, route the reply to the proper replyTo.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thanks for the advice and feedback, appreciate it.I have seen your [examples](https://gist.github.com/garyrussell/8900257) and plan on using them within the **Client** application. In a future development iteration, we look to improve the **Server** application and the queue management, and migrate to exchanges. – Brian Jun 18 '17 at 12:36
  • Would you consider it a sound approach if each scaled **Client** instance created its own unique reply queue and then bound it to the reply exchange that the **Server** application publishes to? The binding would use a routing key that is unique to that instance application such as a UUID. Would it be best to use a direct exchange for the reply exchange? – Brian Jun 18 '17 at 12:43
  • Yes, a direct exchange would be the right type in that case. The cleanest approach, though would be to have the server just send to the `replyTo` property. In Spring AMQP, on the server side, the `MessageListenerAdapter` (and `@RabbitListener`) consider a `replyTo` with format `foo/bar` meaning publish to `foo` with a routing key `bar`. That way, the server doesn't even have to know which exchange he's replying to. – Gary Russell Jun 18 '17 at 14:08