3

I have a JMS Queue that is populated at a very high rate ( > 100,000/sec ).

It can happen that there can be multiple messages pertaining to the same entity every second as well. ( several updates to entity , with each update as a different message. )

On the other end, I have one consumer that processes this message and sends it to other applications.

Now, the whole set up is slowing down since the consumer is not able to cope up the rate of incoming messages.

Since, there is an SLA on the rate at which consumer processes messages, I have been toying with the idea of having multiple consumers acting in parallel to speed up the process.

So, what Im thinking to do is

  • Multiple consumers acting independently on the queue.
  • Each consumer is free to grab any message.
  • After grabbing a message, make sure its the latest version of the entity. For this, part, I can check with the application that processes this entity.
  • if its not latest, bump the version up and try again.

I have been looking up the Integration patterns, JMS docs so far without success.

I would welcome ideas to tackle this problem in a more elegant way along with any known APIs, patterns in Java world.

Anand Hemmige
  • 3,593
  • 6
  • 21
  • 31

3 Answers3

2

ActiveMQ solves this problem with a concept called "Message Groups". While it's not part of the JMS standard, several JMS-related products work similarly. The basic idea is that you assign each message to a "group" which indicates messages that are related and have to be processed in order. Then you set it up so that each group is delivered only to one consumer. Thus you get load balancing between groups but guarantee in-order delivery within a group.

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
0

Most EIP frameworks and ESB's have customizable resequencers. If the amount of entities is not too large you can have a queue per entity and resequence at the beginning.

iwein
  • 25,788
  • 10
  • 70
  • 111
0

For those ones interested in a way to solve this:

As the question is about JMS, we can take a look into an example from Apache Camel website.

This approach is different from other patterns like CBR and Selective Consumer because the consumer is not aware of what message it should process. Let me put this on a real world example:

We have an Order Management System (OMS) which sends off Orders to be processed by the ERP. The Order then goes through 6 steps, and each of those steps publishes an event on the Order_queue, informing the new Order's status. Nothing special here. The OMS consumes the events from that queue, but MUST process the events of each Order in the very same sequence they were published. The rate of messages published per minute is much greater than the consumer's throughput, hence the delay increases over time.

The solution requirements:

  • Consume in parallel, including as many consumers as needed to keep queue size in a reasonable amount.
  • Guarantee that events for each Order are processed in the same publish order.

The implementation:

On the OMS side The OMS process responsible for sending Orders to the ERP, determines the consumer that will process all events of a certain Order and sends the Recipient name along with the Order. How this process know what should be the Recipient? Well, you can use different approaches, but we used a very simple one: Round Robin.

On ERP As it keeps the Recipient's name for each Order, it simply setup the message to be delivered to the desired Recipient.

On OMS Consumer We've deployed 4 instances, each one using a different Recipient name and concurrently processing messages.

One could say that we created another bottleneck: the database. But it is not true, since there is no concurrency on the order line.

One drawback is that the OMS process which sends the Orders to the ERP must keep knowledge about how many Recipients are working.

Alexander
  • 558
  • 4
  • 13