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 <[email protected]> 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.
>
--