JMS topology (Queue with multiple consumers) and message grouping


here is a simplified / schematic topology we set up

[Front server 1 (message producer)] [Front server n (message producer)] | | |________________ ________________| | | [Messaging Server (HornetQ)] | | ________________| |________________ | | [Task server 1 (Message Driven Bean)] [Task server n (MDB)] <ul><li>Each node (server) is a standalone (no cluster) jboss application server (Jboss-as7) including the messaging one. </li> <li>The messaging server deploys many JMS queues.</li> <li>Each Task server deploys a MDB per queue with many consumers.</li> <li>All message producers use the same inbound adapter, all message consumers (MDBs) the same outbound one. In fact all front node are exactly the same (same AS, same config, same deployed artifacts), same for all server nodes.</li> </ul>

Now here is my problem :

the application is a multi-tenant one, for a given queue, some tasks (message processing) must not be processed in parallel for a given tenant, we set up so <a href="http://docs.jboss.org/hornetq/2.2.14.Final/user-manual/en/html_single/#message-grouping" rel="nofollow">message grouping</a> to handle this constraint. The message group is the tenant name and is set by the message producer when sending the message :

message.setStringProperty("JMSXGroupID", tenantName);

On a platform we have 1000+ tenant (so 1000+ different message groups) and for a given queue 3 consumers per server and 3 tasks servers.

When monitoring this queue on the messaging server we can so see thousands messages in queue and 9 consumers. We expects message to be delivered 9 by 9 but in practice the in-delivery message count never exceed 1.

What's the problem here ? is the topology suitable for our needs ?


<a href="https://developer.jboss.org/thread/265934" rel="nofollow">Answer from jboss hornetq support forum</a> (crédits Justin Bertram):


As I'm sure you're aware, a queue has first-in-first-out (i.e. FIFO) semantics. Grouped messages basically act like a bottleneck on the queue since they ensure serial message processing. Here's a simple example...

Consider groups A, B, and C which contain two messages each for a total of 6 messages in the queue. Also consider that they are in the order A, A, B, B, C, C. Now consider 3 different consumers each consuming a different group. The consumer for group A will receive the first message, process it, and acknowledge it so that it is removed from the queue. Then it will receive the second message, process it, and acknowledge it so that it is removed from the queue. During the time the consumer for group A is busy with these 2 messages no other messages can be consumed from the queue. Only when the second message is acknowledged can the consumer for group B actually receive the first message in group B. Once the consumer for group B acknowledges both of its messages the consumer for group C can finally receive the messages in its group. This behavior is governed by the FIFO semantics of the queue. The messages in group B can't leap-frog the messages in group A and be consumed before all the messages in group A are consumed. The same goes for the messages in group C.

Since all your messages are in a group I would never expect the in-delivery count to exceed 1.



  • When should I use `REQUIRED` vs `NOT_SUPPORTED` as a the value of @TransactionAttribute for an MDB?
  • How is logback's “prudent mode” implemented?
  • RabbitMq and “Fatal error: handshake failure - handshake_decode_error”
  • How to send correlation id, into message, from sender and retrieval from receive into message header
  • How to design a distributed application using a Message Broker and a Database?
  • BPEL Designer for Eclipse: how to debug a BPEL process
  • Is it possible to secure whole Controller in Symfony 2?
  • how to replace string in SpEL expression?
  • Algorithms that lead to java.lang.OutOfMemoryError: PermGen space error
  • EventBus on Android: how to implement dynamic queues vs. class-based event subscription?
  • ColdFusion with IIS URL Rewrite - Page never finishes loading
  • Doctrine fixtures not working after updating to Symfony 2.1.8
  • MSMQ on Azure Website
  • NullPointer in Glassfish when inject JMS @Resource
  • Azure Resource Template Deployment issues
  • Deploy same Javascript webapp build to different environments
  • Column Nullability/Optionality: NULL vs NOT NULL
  • stringify/parse edn in clojure/ClojureScript
  • oracle row contention causing deadlock errors in high throughtput JMS application
  • BizTalk Party not being resolved for incoming HL7v2 message
  • Trouble connecting to Google Cloud SQL server from deployed app
  • Microsoft Chart Controls for Microsoft .NET Framework 4.0
  • How to distribute an event to all nodes in a (Wildfly) cluster?
  • Error “Reflect.defineMetadata” while trying to load a transient web worker
  • Using an enum contained in a Cloud Endpoint model on a Android client
  • Unicorn and Rails eat up 2x MySQL connections
  • Spring Integration Bridge with poller not working as expected for JMS
  • Laravel 4 routing not working due to .htaccess file?
  • How to make Twilio api Post request with the help of AFNetworking?
  • Should I or shouldn't I use the CachingConnectionFactory with hornetq 2.4.1
  • WPF - CanExecute dosn't fire when raising Commands from a UserControl
  • What is the “return” in scheme?
  • Menu Color Fade on Hover with Jquery
  • Invalid access key error using credentials redeemed from an amazon open id token
  • Circular dependency while pushing http interceptor
  • InvalidAuthenticityToken between subdomains when logging in with Rails app
  • What are the advantages and disadvantages of reading an entire file into a single String as opposed
  • How to stop GridView from loading again when I press back button?
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • UserPrincipal.Current returns apppool on IIS