I did the test again with a pur Spring DMLC: public class CamelSpringDMLCConsumerPerformanceTest {
private static final String PAYLOAD = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxx"; private int counter = 3000; private BrokerService broker; private DefaultMessageListenerContainer dmlc; private JmsTemplate template; private CountDownLatch latch = new CountDownLatch(counter); @Before public void setUp() throws Exception { broker = new BrokerService(); broker.setPersistent(true); broker.setUseJmx(false); broker.addConnector("tcp://localhost:61616"); broker.start(); ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); template = new JmsTemplate(connectionFactory); template.setSessionTransacted(false); template.setDefaultDestinationName("test"); template.setPubSubDomain(false); template.afterPropertiesSet(); dmlc = new DefaultMessageListenerContainer(); dmlc.setCacheLevelName("CACHE_CONSUMER"); dmlc.setSessionTransacted(false); dmlc.setDestinationName("test"); dmlc.setConnectionFactory(connectionFactory); dmlc.setPubSubDomain(false); MessageListener messageListener = new MyMessageListener(latch); dmlc.setMessageListener(messageListener); dmlc.afterPropertiesSet(); } @After public void tearDown() throws Exception { dmlc.stop(); broker.stop(); } @Test public void test() throws Exception { for (int i = 0; i < counter; i++) { template.convertAndSend(PAYLOAD); } dmlc.start(); assertTrue(latch.await(1, TimeUnit.MINUTES)); } public static class MyMessageListener implements MessageListener { private static final Logger log = LoggerFactory.getLogger(MyMessageListener.class); private CountDownLatch latch; public MyMessageListener(CountDownLatch latch) { this.latch = latch; } @Override public void onMessage(Message message) { latch.countDown(); try { log.info(((TextMessage) message).getText()); } catch (JMSException e) { e.printStackTrace(); } } } } And got the following log output: 2012-12-16 19:40:22,003 [enerContainer-1] INFO formanceTest$MyMessageListener - xx... // message 1 --- 2012-12-16 19:40:23,963 [enerContainer-1] INFO formanceTest$MyMessageListener - xx... // message 3000 Which means a pur Spring DMLC needs 1,96 seconds to consume 3000 messages. This is very close to the 2,2 seconds Camel needs. I cannot reproduce the "ridiculously worse" performance you measured - at least not with ActiveMQ. Best, Christian On Wed, Dec 5, 2012 at 11:09 PM, Christian Müller < christian.muel...@gmail.com> wrote: > I set up the following test with Camel 2.10.2: > > public class CamelActiveMQConsumerPerformanceTest extends CamelTestSupport > { > > private static final String PAYLOAD = > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + > "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > + "xxxxxxxxxxxxxxxxxxxxxxxx"; > > private int counter = 3000; > private BrokerService broker; > > @Before > public void setUp() throws Exception { > broker = new BrokerService(); > broker.setPersistent(true); > broker.setUseJmx(false); > broker.addConnector("tcp://localhost:61616"); > broker.start(); > > super.setUp(); > } > > @After > public void tearDown() throws Exception { > super.tearDown(); > > broker.stop(); > } > > @Test > public void test() throws Exception { > template.setDefaultEndpointUri("activemq:queue:test"); > > for (int i = 0; i < counter; i++) { > template.sendBody(PAYLOAD); > } > > final CountDownLatch latch = new CountDownLatch(counter); > context.addRoutes(new RouteBuilder() { > public void configure() throws Exception { > > from("activemq:queue:test?acknowledgementModeName=DUPS_OK_ACKNOWLEDGE") > .process(new Processor() { > public void process(Exchange exchange) throws > Exception { > latch.countDown(); > log.info > (exchange.getIn().getBody(String.class)); > } > }); > } > }); > > assertTrue(latch.await(1, TimeUnit.MINUTES)); > } > > @Override > protected JndiRegistry createRegistry() throws Exception { > JndiRegistry registry = super.createRegistry(); > registry.bind("activemq", > ActiveMQComponent.activeMQComponent("tcp://localhost:61616")); > return registry; > } > } > > And got the following log output: > > 2012-12-05 22:57:06,122 [sConsumer[test]] INFO > iveMQConsumerPerformanceTest$1 - xx... // message 1 > ... > 2012-12-05 22:57:08,333 [sConsumer[test]] INFO > iveMQConsumerPerformanceTest$1 - xx... // message 3000 > > Which means camel-activemq needs 2,2 seconds to consume 3000 messages. Not > so bad... > I'm wondering why you have so bad numbers in your test... > > Best, > Christian > > On Wed, Aug 8, 2012 at 5:31 PM, northface01 <northfac...@gmail.com> wrote: > >> I did a simple throughput test where I have about 3k large messages each >> has >> a size of 1KB+ in a Solace JMS queue. I set up a simple camel route which >> just consume the 3k messages and send them to a bean which simply logs the >> message body. With this approach I was able to consume and log all >> messages >> in 28-30 seconds, which translates to about 100 messages per second. >> However, when I used a Spring DMLC to consume with the same bean as the >> message listener which also simply logs the message body, I got all >> messages >> consumed and logged in about 1 second, which is about 3k messages per >> second. I understand camel-jms component is not designed with performance >> as >> the top priority but this huge performance between camel-jms and spring >> DMLC >> doesn't make any sense. I haven't got time to trace down the root cause of >> this huge overhead by camel-jms myself. I would appreciate if someone who >> is >> more familiar with camel-jms code can take a quick look at this issue. >> BTW, >> I was able to use the new camel-sjms component to consume the same 3k >> messages in about 1.5 seconds which meets my throughput target so I didn't >> have to fix camel-jms myself or write my own jms component. So kudos to >> the >> developers of camel-sjms. >> >> Here is my camel context: >> >> <beans xmlns="http://www.springframework.org/schema/beans" >> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >> xmlns:camel="http://camel.apache.org/schema/spring" >> xmlns:context="http://www.springframework.org/schema/context" >> xmlns:tx="http://www.springframework.org/schema/tx" >> xsi:schemaLocation="http://www.springframework.org/schema/beans >> http://www.springframework.org/schema/beans/spring-beans-3.0.xsd >> http://camel.apache.org/schema/spring >> http://camel.apache.org/schema/spring/camel-spring-2.9.2.xsd >> http://www.springframework.org/schema/context >> http://www.springframework.org/schema/context/spring-context-3.0.xsd >> http://www.springframework.org/schema/tx >> http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> >> >> <context:load-time-weaver/> >> >> <bean id="placeholderProperties" >> >> class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> >> <property name="location" >> value="classpath:${camel.properties}"/> >> <property name="systemPropertiesModeName" >> value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> >> <property name="ignoreUnresolvablePlaceholders" >> value="true"/> >> <property name="order" value="1"/> >> </bean> >> >> <camel:errorHandler id="noErrorHandler" type="NoErrorHandler"/> >> >> <bean id="shutdown" >> class="org.apache.camel.impl.DefaultShutdownStrategy"> >> <property name="timeout" value="0"/> >> </bean> >> >> <bean id="msgTest" class="Test"/> >> >> <camel:camelContext id="steam-camel" >> xmlns="http://camel.apache.org/schema/spring"> >> <jmxAgent id="agent" disabled="true"/> >> <endpoint id="steam-solace" >> uri="jms:${queue.name >> }?jmsMessageType=Text&cacheLevelName=CACHE_CONSUMER"/> >> <route errorHandlerRef="noErrorHandler" >> shutdownRunningTask="CompleteAllTasks"> >> <from uri="ref:steam-solace"/> >> <to uri="bean:msgTest?method=onText"/> >> </route> >> </camel:camelContext> >> >> <bean id="jndiTemplate" >> class="org.springframework.jndi.JndiTemplate"> >> <property name="environment"> >> <props> >> <prop >> key="java.naming.provider.url">${jms.provider.url}</prop> >> <prop >> key="java.naming.factory.initial">${jms.factory.initial}</prop> >> <prop >> key="java.naming.security.principal">${jms.security.principal}</prop> >> <prop >> key="java.naming.security.credentials">${jms.security.credentials}</prop> >> <prop key="Solace_JMS_JNDI_ClientID">${ >> jms.client.id}-JNDI</prop> >> <prop >> key="Solace_JMS_VPN">${jms.solace.vpn}</prop> >> </props> >> </property> >> </bean> >> >> <bean id="jmsConnectionFactory" >> class="org.springframework.jndi.JndiObjectFactoryBean"> >> <property name="jndiTemplate" ref ="jndiTemplate"/> >> <property name="jndiName" >> value="${jms.connection.factory}"/> >> </bean> >> >> <bean id="connectionFactory" >> class="org.springframework.jms.connection.CachingConnectionFactory"> >> <property name="targetConnectionFactory" ref >> ="jmsConnectionFactory"/> >> <property name="sessionCacheSize" value="10"/> >> <property name="clientId" value="${jms.client.id}"/> >> </bean> >> >> <bean id="jmsConfig" >> class="org.apache.camel.component.jms.JmsConfiguration"> >> <property name="connectionFactory" >> ref="connectionFactory"/> >> <property name="asyncConsumer" value="true"/> >> <property name="disableReplyTo" value="true"/> >> <property name="acknowledgementModeName" >> value="DUPS_OK_ACKNOWLEDGE"/> >> <property name="concurrentConsumers" value="1"/> >> <property name="maxConcurrentConsumers" value="1"/> >> <property name="idleTaskExecutionLimit" value="1"/> >> <property name="idleConsumerLimit" value="1"/> >> </bean> >> >> <bean id="jms" >> class="org.apache.camel.component.jms.JmsComponent"> >> <property name="configuration" ref="jmsConfig"/> >> </bean> >> >> </beans> >> >> Here is my Spring DMLC context: >> <beans xmlns="http://www.springframework.org/schema/beans" >> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >> xmlns:camel="http://camel.apache.org/schema/spring" >> xmlns:context="http://www.springframework.org/schema/context" >> xmlns:tx="http://www.springframework.org/schema/tx" >> xsi:schemaLocation="http://www.springframework.org/schema/beans >> http://www.springframework.org/schema/beans/spring-beans-3.0.xsd >> http://camel.apache.org/schema/spring >> http://camel.apache.org/schema/spring/camel-spring-2.9.2.xsd >> http://www.springframework.org/schema/context >> http://www.springframework.org/schema/context/spring-context-3.0.xsd >> http://www.springframework.org/schema/tx >> http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> >> >> <context:load-time-weaver/> >> >> <bean id="placeholderProperties" >> >> class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> >> <property name="location" >> value="classpath:${camel.properties}"/> >> <property name="systemPropertiesModeName" >> value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> >> <property name="ignoreUnresolvablePlaceholders" >> value="true"/> >> <property name="order" value="1"/> >> </bean> >> >> <bean id="msgListener" class="Test"/> >> >> <bean id="DMLC" >> class="org.springframework.jms.listener.DefaultMessageListenerContainer"> >> <property name="cacheLevelName" value="CACHE_CONSUMER" /> >> <property name="sessionTransacted" value="false" /> >> <property name="destinationName" value="${jms.queue.name}" /> >> <property name="connectionFactory" ref="connectionFactory" /> >> <property name="pubSubDomain" value="false" /> >> <property name="messageListener" ref="msgListener" /> >> </bean> >> >> >> <bean id="jndiTemplate" >> class="org.springframework.jndi.JndiTemplate"> >> <property name="environment"> >> <props> >> <prop >> key="java.naming.provider.url">${jms.provider.url}</prop> >> <prop >> key="java.naming.factory.initial">${jms.factory.initial}</prop> >> <prop >> key="java.naming.security.principal">${jms.security.principal}</prop> >> <prop >> key="java.naming.security.credentials">${jms.security.credentials}</prop> >> <prop key="Solace_JMS_JNDI_ClientID">${ >> jms.client.id}-JNDI</prop> >> <prop >> key="Solace_JMS_VPN">${jms.solace.vpn}</prop> >> </props> >> </property> >> </bean> >> >> <bean id="jmsConnectionFactory" >> class="org.springframework.jndi.JndiObjectFactoryBean"> >> <property name="jndiTemplate" ref ="jndiTemplate"/> >> <property name="jndiName" >> value="${jms.connection.factory}"/> >> </bean> >> >> <bean id="connectionFactory" >> class="org.springframework.jms.connection.CachingConnectionFactory"> >> <property name="targetConnectionFactory" ref >> ="jmsConnectionFactory"/> >> <property name="sessionCacheSize" value="10"/> >> <property name="clientId" value="${jms.client.id}"/> >> </bean> >> >> </beans> >> >> Here is my Test bean which logs the messages: >> public class Test implements MessageListener { >> private Logger logger = Logger.getLogger(Test.class); >> >> @Override >> public void onMessage(Message message) { >> try { >> logger.debug(((TextMessage)message).getText()); >> } catch (Exception e) { >> logger.error(message, e); >> } >> } >> >> public void onText(String text) { >> logger.debug(text); >> } >> >> } >> >> >> >> -- >> View this message in context: >> http://camel.465427.n5.nabble.com/Camel-JMS-Performance-is-ridiculously-worse-than-pure-Spring-DMLC-tp5716998.html >> Sent from the Camel Development mailing list archive at Nabble.com. >> > > > > -- > > > --