I have a requirement to upgrade our Producer/Consumer infrastructure.
The current setup look like this:
- Set of 3 queues with different priority (low, med, high).
- When one our customers generate a task (i.e Process an image):
- The Producer add the message to the relevant queue.
- One of the workers address it.
The issue with such approach, is that in case and a customer generate a huge amount of tasks, it can occupy all available slots in queue, which potentially can lead to deny of service (or a huge delay) in that queue.
Suggested changes:
- Each customer (or a group of) should have dedicated Consumer (or a group of).
- When the Consumers are idle, they should process other customers' messages.
For example, We have a set of messages:
1. Producer: Customer1, Queue: High, Payload: {}, Created: Today 16:00:00
2. Producer: Customer2, Queue: High, Payload: {}, Created: Today 16:00:01
3. Producer: Customer1, Queue: High, Payload: {}, Created: Today 16:00:02
4. Producer: Customer1, Queue: High, Payload: {}, Created: Today 16:00:03
And we have the following Consumers:
1. Consumer1: Dedicated for Customer1
2. Consumer2: Dedicated for Customer1
3. Consumer3: Dedicated for Customer2
Expected result:
1. Consumer1 will address Message#1
2. Consumer2 will address Message#2
3. Consumer3 will address Message#3
4. Message#4 Any of the Consumers can address it, since Consumer1/3 are dedicated to the given Producer and Consumer2 will be idle.
To sum things up, a customer should always get a dedicated amount of Consumers (or more when available) ASAP, whenever there is nothing to do, his Consumers can consume other messages of other customers.
I'm trying to figure out what is the best approach to achieve that goal even on the expense of switching from RabbitMQ to any other messaging broker.
The only approach I've found (Using RabbitMQ) so far is to use federate queues and to form a complete bi-directional graph (each queue is a upstream of all other queues and vise versa).