Search code examples
javarabbitmqamqpspring-amqp

Best way handle partitioned data with AMQP?


I have several similar systems which are authoritative for different parts of my data, but there's no way I can tell just from my "keys" which system owns which entities.

I'm working to build this system on top of AMQP (RabbitMQ), and it seems like the best way to handle this would be:

  1. Create a Fanout exchange, called thingInfo, and have all of my other systems bind their own anonymous queues to that exchange.
  2. Send a message out to the exchange: {"thingId": "123abc"}, and set a reply_to queue.
  3. Wait for a single one of the remote hosts to reply to my message, or for some timeout to occur.

Is this the best way to go about solving this sort of problem? Or is there a better way to structure what I'm looking for? This feels mostly like the RPC example from the RabbitMQ docs, except I feel like using a broadcast exchange complicates things.

I think I'm basically trying to emulate the model described for MCollective's Message Flow, but, while I think MCollective generally expects more than one response, in this case, I would expect/require precisely one or, preferably, a clear "nope, don't have it, go fish" response from "everyone" (if it's really possible to even know that in this sort of architecture?).

Perhaps another model that mostly fits is "Scatter-Gather"? It seems there's support for this in Spring Integration.


Solution

  • It's a reasonable architecture (have the uninterested consumers simply ignore the message).

    If there's some way to extract the pertinent data that the consumers use to decide interest into headers, then you can gain some efficiency by using a topic exchange instead of a fanout.

    In either case, it gets tricky if more than one consumer might reply.

    As you say, you can use a timeout if zero consumers reply, but if you think that might be frequent, you may be better off using arbitrary two-way messaging and doing the reply correlation in your code rather than using request/reply and tying up a thread waiting for a reply that will never come, and timing out.

    This could also deal with the multi-reply case.