Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jms producer performance with spring

Tags:

i created a simple producer consumer simulation based on spring, jms and activemq, i'm trying to reach high performance from both sides, producers and consumers,

Connection settings :

<tx:annotation-driven /> <bean id="transactionManager" class="org.springframework.jms.connection.JmsTransactionManager">      <property name="connectionFactory"  ref="connectionFactory" /> </bean>  <amq:connectionFactory id="amqConnectionFactory" brokerURL="failover:(tcp://${broker.url}:61616)"  />  <bean id="connectionFactory"     class="org.springframework.jms.connection.CachingConnectionFactory">     <property name="targetConnectionFactory" ref="amqConnectionFactory" /> </bean>  <amq:queue id="queue" physicalName="queue" />  <beans:bean id="jsonMessageConverter" class="XXXXX.converter.JsonMessageConverter" /> 

Consumer settings :

<jms:listener-container concurrency="10"     acknowledge="auto" prefetch="1" message-converter="jsonMessageConverter" transaction-manager="transactionManager"      >     <jms:listener id="queueListener_1" destination="ooIntegrationQueue"         ref="myMessageListenerAdapter" /> </jms:listener-container>   <beans:bean id="myMessageListenerAdapter"     class="org.springframework.jms.listener.adapter.MessageListenerAdapter" >     <beans:property name="delegate" ref="consumer"/> </beans:bean>   <beans:bean id="consumer" class="XXX.ConsumerImpl"/> 

Producer settings :

<beans:bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"     p:connectionFactory-ref="connectionFactory" p:messageConverter-ref="jsonMessageConverter"     p:defaultDestination-ref="ooIntegrationQueue" p:sessionTransacted="true" /> 

starting with the consumer, i managed to consume about 25 messages per second, which is extremely slow, i discovered the bottleneck to be the fact that i am using transactions, after googling for a bit, and playing with the configs, i found out that after autowiring the DefaultMessageListenerContainer and changing the cachelevel to

listenerContainer.setCacheLevelName("CACHE_SESSION")  

my performance increases to about 1500 messages per second while still having transactions.

my problem is now with the producer which is still stuck at about 25 operations per sec, my producer test is simple :

int numOfMessages = getNumberOfMessages();   double startTime = System.currentTimeMillis();  for (int i = 1; i <= numOfMessages; i++) {     jmsTemplate.convertAndSend("HelloWorld" + i); }  double endTime = System.currentTimeMillis();  double totalTime=(endTime-startTime)/1000; System.out.println("Time - "+totalTime+" seconds"); System.out.println("EPS - "+numOfMessages/totalTime); 

i'm wondering how to reach similiar performances with the producer, since it now bottlenecks the entire system.

like image 276
Matan Avatar asked Aug 14 '11 10:08

Matan


2 Answers

Sorry if this answer comes to late to help the original poster. I recently investigated JmsTemplate performance. Even with the same delivery and acknowledgment modes, native JMS code seemed much faster than JmsTemplate. The problem turned out to be that ActiveMQ normally defaults to async sending, but when you use JmsTemplate it instead uses sync sending. This dramatically reduces performance. You can set ActiveMQConnectionFactory's useAsyncSend property to true to force async sending. More details here: JmsTemplate is not evil

like image 175
Christopher Wong Avatar answered Oct 09 '22 19:10

Christopher Wong


JMSTemplate does a walk of ConnectionFactiory -> Connection -> Session -> MessageProducer, closing each object after each send. To get around this, wrap your amqConnectionFactory bean with a org.apache.activemq.pool.PooledConnectionFactory, and use that under the template rather than a CachingConnectionFactory.

like image 24
Jakub Korab Avatar answered Oct 09 '22 19:10

Jakub Korab