Friday, October 23, 2009

JMS and Spring 3.0 rc1 and some recommendations

So, I got to play with Spring and ActiveMQ this sprint for a little application we are writing at work. I've been looking for a project which could use JMS for a while, and this one seemed to fit the bill perfectly. Like I said in my last post, I found the experience doing the configuration to be very straight forward and there were lots of information out there to set this up (especially Spring in Action).

The few pieces that I found scattered about in many places which I would recommend are:
  1. Use a pooled connection factory with Spring. The JMS Template is rather heavy as it opens and closes a connection every message as well as other over head. A serious waste and ActiveMQ recommends using theirs.
  2. With the message listener, be sure to include the destroy-method="shutdown" attribute as without it, there is no guarantee that your consumers will be terminated correctly (a problem we ran into without realizing it for a few days)
  3. Add maxConcurrentConsumers to increase the number of consumers to help process the messages. This will dynamically change the number of consumers based on need and has tested to be a big win for us.
Otherwise, this is really simple to get up and running. It has been a HUGE help in terms of performance and seems to be very stable under our load tests thus far. I included my configuration below in case you would like to use it as a template.

Some resources:
http://activemq.apache.org/
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch21.html

<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
   <constructor-arg index="0" value="${activemq.destination.name}">
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
   <property name="connectionFactory" ref="jmsFactory">
   <property name="defaultDestination" ref="pruneDestination">
</bean>

<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" method="stop">
   <property name="connectionFactory">
   <bean class="org.apache.activemq.ActiveMQConnectionFactory">
      <property name="brokerURL" value="${activemq.broker.url}">
   </bean>
   </property>
</bean>

<bean id="messageListener" class="some.path.to.a.MessageListener">
   <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" method="shutdown">
   <property name="connectionFactory" ref="jmsFactory">
   <property name="destination" ref="destination">
   <property name="messageListener" ref="messageListener">
   <property name="maxConcurrentConsumers" value="5">
</bean>

1 comment:

  1. Good stuff, seems right on with what I posted a few days ago. I would recommend using the CachedConnectionFactory over AMQ's PooledConnectionFactory though. Also using the jms namespace makes the spring config much cleaner looking.

    ReplyDelete