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&amp;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.
>>
>
>
>
> --
>
>
>


--

Reply via email to