1
votes

I am trying to find the fastest way using Camel to transfer messages from one ActiveMQ Artemis queue to another. I thought that Camel's SJMS2 component would be faster than Camel's traditional JMS component, but routing with the JMS component is 2.5 times faster (20,000 vs 8,000 msg/s). I use Camel version 2.20.2 and Artemis version 2.11.0.

Route with JMS

import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.JndiRegistry;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;
import org.messaginghub.pooled.jms.JmsPoolConnectionFactory;

import javax.jms.ConnectionFactory;
import java.util.concurrent.TimeUnit;

public class JMSTransferTest extends CamelTestSupport {
    @Test
    public void testArtemis() throws Exception {
        TimeUnit.SECONDS.sleep(100);
    }

    @Override
    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            public void configure() {
                from("jms://TEST.IN?connectionFactory=#artemisCF&concurrentConsumers=200")
                        .to("jms://TEST.OUT?connectionFactory=#artemisCF");
            }
        };
    }

    @Override
    protected JndiRegistry createRegistry() throws Exception {
        JndiRegistry registry = super.createRegistry();

        final ConnectionFactory connFactory = new ActiveMQConnectionFactory("tcp://localhost:61622");
        final ConnectionFactory connFactoryDeadLeatter = new ActiveMQConnectionFactory("tcp://localhost:61622");
        JmsPoolConnectionFactory pooledConnectionFactory = new JmsPoolConnectionFactory();

        pooledConnectionFactory.setConnectionFactory(connFactory);
        pooledConnectionFactory.setMaxConnections(20);
        pooledConnectionFactory.setMaxSessionsPerConnection(100);
        registry.bind("artemisCF", pooledConnectionFactory);
        registry.bind("deadLetterCF", connFactoryDeadLeatter);
        return registry;
    }
}

Route with SJMS2, other settings as in the code above

@Override
protected RouteBuilder createRouteBuilder() throws Exception {
    return new RouteBuilder() {
        public void configure() {
            from("sjms2://TEST.IN?connectionFactory=#artemisCF&consumerCount=200&asyncStartListener=true")
                    .to("sjms2://TEST.OUT?connectionFactory=#artemisCF");
        }
    };
}

How can I use the SJMS2 component to get the same speeds as JMS component?

1
Have you run both routes using a profiler to see where the most time is being taken?Justin Bertram
No, I haven't used it yet. Can I ask for a link where can I read more?Lukyanov Mikhail
There are lots of Java profilers available. This article does a good job summarizing the options.Justin Bertram
Thanks, I will read and tryLukyanov Mikhail

1 Answers

1
votes

Claus Ibsen replied on the mailing list as follows

200 consumers is too much. That instead makes it slower as you have 200 consumers racing for messages. Instead try to find a lower balance that is closer to cpu cores etc.

Also often a JMS client has a prefetch buffer (or some concept like this) which means a consumer may pre-download 1000 messages and then the other 199 consumers cant process these messages. So you need to tweak this option too.

Also if you have too many consumers and remote network connections then you get too chatty over IO etc. So its all about tuning depending on use-cases.

spring-jms has a thread pool built in that can automatic grow/shrink depending on load, and this can explain why its out of the box without tuning can appear to be faster.

Writing such logic is a bit more complex and this hasnt been added to sjms. I created a ticket about this https://issues.apache.org/jira/browse/CAMEL-14637

You can get in touch with commercial Camel supports as there are companies and consultants that has great experience with JMS brokers and Camel and to get them tuned to very high performance. The settings for JVM and OS and hardware can all make a big difference.

And I also found a good article on this topic https://dzone.com/articles/performance-tuning-ideas-for-apache-camel