Tuning Message Bus performance in Servicemix

Posted by dave
on May 21, 2008 @ 10:21 PM

How fast you can send messages through ServiceMix is highly dependent on how the embedded ActiveMQ broker within ServiceMix is configured. This is because the ServiceMix NMR uses ActiveMQ as its messaging engine, so choosing the correct connection factories and persistenceAdapter can give you easy gains in performance.

AMQ Message Store

In ActiveMQ 5.0, a new high performance journaling persistence adapter was introduced called the AMQ Message Store.

To enable it, edit /conf/activemq.xml and modify the xbean config, adding the amq:persistenceAdapter element.
1
2
3
4
5
6
7
8
 <amq:persistenceAdapter>
         <!-- Goodbye journaledJDBC --> 
         <!--amq:journaledJDBC journalLogFiles="5" dataDirectory="./data/amq"/ -->

         <!-- Hello AMQ Message Store -->
         <amq:amqPersistenceAdapter directory="file://./data/amq"/>

 </amq:persistenceAdapter>

And by the numbers ..

Example Flow: Jms consumer -> JMS provider(w/Marshaller) -> EIP pipeline -> Bean -> JMS Provider MessageCount: 10000

   With JournaledJDBC:

   [java] Overall time: 137701 ms
   [java] Messages per sec: 7.262111386264443
   [java] 
   [java] Time: 139.603
   [java]
   [java] OK (1 test)
   With AMQ Message Store:

   [java] Overall time: 20511 ms
   [java] Messages per sec: 48.75432694651651
   [java]
   [java] Time: 23.556
   [java]
   [java] OK (1 test)

Two additional steps:

1) The current version of Servicemix trunk is using 4.1.1 of ActiveMQ, so if you want to build a ServiceMix distribution that contains ActiveMQ 5, you need to edit /trunk/pom.xml:

1
2
3
/trunk/pom.xml
-        <activemq-version>4.1.1</activemq-version>
+        <activemq-version>5.1.0</activemq-version>

2) Once the activemq-version is updated, the ra namespace in jndi.xml needs to be updated too - as this changed between AMQ versions.

/distributions/apache-servicemix/src/main/release/conf/jndi.xml
-       xmlns:amqra="http://activemq.org/ra/1.0"
+       xmlns:amqra="http://activemq.apache.org/schema/ra"

If your using Fuse ESB, it has a 5.x version of the Fuse Message Broker included, so the XML configuration change should be all thats required.

High performance integration between an iPhone and the Chumby

Posted by dave
on May 19, 2008 @ 05:17 PM

This Artix/E demo is pretty cool.

An iPhone is shown using Artix/E to talk to a Chumby. The accelerometer data from the iPhone is streamed over the wire to the chumby's chumball widget.

Artix/E's job here was to provide the low level infrastructure that allows both devices to seamlessly talk to each other, the main highlights being:

- Very lightweight/small footprint for embedded devices.
- Provides a contract based services framework.
- High performance transport, so good for applications with time sensistive data.
- Cross platform & portable.

Deciphering a Servicemix Service Assembly build error

Posted by dave
on May 16, 2008 @ 12:36 PM
[INFO] The service unit my-jms-consumer-su does not have a dependency which is packaged as a jbi-component or a project property 'componentName'

If you see the above error when trying to build your servicemix service assembly, the trick is to look at the pom.xml for the component with the problem. In this case the ServiceMix SU is'my-jms-consumer-su'.

In order to fix the Service Assembly build error I added the componentName to the SU's pom.xml below properties section, so
1
2
3
        <properties>
                <servicemix-version>3.3.1.0-fuse</servicemix-version>
        </properties>
became:
1
2
3
4
        <properties>
                <servicemix-version>3.3.1.0-fuse</servicemix-version>
                <componentName>servicemix-jms</componentName>
        </properties>

This problem only tends to occur when you have multiple su's within the assembly that depend on the same servicemix component (e.g. servicemix-jms). Make sure you add the componentName to all of the Service Unit poms.xml's that use that component.

Using the Spring based JMS Endpoints in Servicemix

Posted by dave
on May 14, 2008 @ 05:07 PM

I've been running performance tests with Fuse ESB 3.3.1 and the spring based JMS endpoints over the last day or two.

One gotcha I've seen mentioned before with ActiveMQ is on the producer side you need to use a PooledConnectionFactory when using springs jmsTemplate. The same applies when using the Servicemix jms:provider endpoint (as its using jmsTemplate under the covers).

If your jms provider configuration looks similar to this:
1
2
3
4
5
6
7
8
9
10
11
 <jms:provider
      service="test:MySpringProviderService"
      endpoint="mySpringProvider"
      destinationName="queue/OUT"
      connectionFactory="#connectionFactory"
      pubSubDomain="false"
      stateless="false" />

 <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="tcp://localhost:61616" />
 </bean>

change the connectionFactory to something like this:

1
2
3
4
5
6
7
8
9
 <bean id="connectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
    <property name="connectionFactory">
      <bean class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616" />
      </bean>
    </property>
    <property name="maxConnections" value="1" />
    <property name="maximumActive" value="1" />
  </bean>

Then by the numbers for my test flow (Jms Consumer->EIP->Bean->JMS Provider & processing/10K worth of messages) ...

Pooled ConnectionFactory:
     [java] Overall time: 40360 ms
     [java] Messages per sec: 247.77006937561944
     [java] 
     [java] Time: 41.064
     [java] 
     [java] OK (1 test)
     [java]    
Non-Pooled ConnectionFactory:
     [java] Overall time: 908363 ms
     [java] Messages per sec: 11.008814757976712
     [java] 
     [java] Time: 909.34
     [java] OK (1 test)
     [java] 
 

Those couple of lines of XML make a big difference. Without the pool, the JMS connection is torn down each time and that accounts for the disparity.

A second area to look out for is the jms:consumer endpoint configuration. Make sure you set the cacheLevel to CACHE_CONNECTION (1) or CACHE_CONSUMER (3). The default is CACHE_NONE. Below we set the cacheLevel for the underlying DefaultMessageListenerContainer to CACHE_CONSUMER

1
2
3
4
5
6
7
  <jms:consumer service="test:MySpringConsumerService"
        endpoint="mySpringConsumer"
        targetService="test:MySpringProviderService"
        destinationName="queue/SPRING_IN"
        connectionFactory="#connectionFactory"
        concurrentConsumers="1"
        cacheLevel="3"/>
I hope these two tips will help you fine tune your Servicemix performance.