16 Apr 2009

Slower performance with the new servicemix-jms endpoints?


There are two servicemix-jms components available in the later versions of ServiceMix 3. The traditional jms endpoint that is configured using <jms:endpoint> and the new jms endpoint that uses <jms:consumer>; and <jms:provider>. The new JMS endpoints reuse much of Spring JMS. Very recently I noticed a pretty large performance difference between these two JMS consumers, in the way that the new servicemix-jms consumer was much slower than the traditional consumer while using a pretty default configuration for both.
The reason for that is that out of the box the new JMS endpoint is configured to use the Spring JMS DefaultMessageListenerContainer without any caching, so all JMS resources get re-created and closed for every message being sent or received. This of course degrades performance a lot.

There are two simple solutions:

1) Configure caching for this DMLC

<jms:consumer service="test: NewJMSConsumer"
endpoint="endpoint"
targetservice="test:bean"
targetendpoint="endpoint"
destinationname="queue/TEST.FOO"
connectionfactory="#AMQConnectionFactory"
cachelevel="3">


Using cacheLevel="3" (CACHE_CONSUMER) is the highest cache option and caches the pretty much all JMS resources for each listener thread (JMS connection, session and message consumer). Other levels are 2 (CACHE_SESSION ), 1 (CACHE_CONNECTION) and 0 (CACHE_NONE). If no cacheLevel is specified, CACHE_NONE is used!

2) Or configure for a different Spring JMS listener

<jms:consumer service="test:NewJMSConsumer"
endpoint="endpoint"
targetservice="test:bean"
targetendpoint="endpoint"
destinationname="queue/TEST.FOO"
connectionfactory="#AMQConnectionFactory"
listenertype="server">


The ServerSessionMessageListenerContainer type internally uses a ServerSessionPool (which as the name suggests pools the server sessions) and also results in reasonable performance. However this listener type might not be suitable for all deployments.

Both options should boost performance and perform equally fast as the old JMS endpoint. These jms consumer attributes are both documented but it is easy to overlook them and just use the default configuration.
I recommend solution 1, using the DefaultMessageListenerContainer and enable caching.

Finally there seems no reason why caching could not be turned on by default. So I raised JIRA SM-1841 at Apache.

3 comments:

asolntsev said...

Torsten,
This is a really useful post for me.

Thanks a lot!

@ said...

Thanks for the tip,
easily overlooked in the core documentation...
Saves my day ....

Sandeep said...

I am wondering how is the jms:consumer thing working at all. I am using fusesource and when I do maven install I get a jbi which does not contain service names of consumers and providers?

Can you please help me understand this?
s/w :Fusesource 4.3.1.00

thanks
Sandeep
sandeepch@gmail.com