我正在尝试找到使用Camel将消息从一个ActiveMQ Artemis队列传输到另一个队列的最快方法。我认为Camel的SJMS2组件会比Camel的传统JMS组件快,但使用JMS组件的路由速度快2.5倍(20,000 vs 8,000 msg/s)。我使用Camel版本2.20.2和Artemis版本2.11.0。
使用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;
}
}
使用SJMS2路由,其他设置如上代码所示
@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");
}
};
}
如何使用SJMS2组件获得与JMS组件相同的速度?
克劳斯·易卜生在邮件列表中回复如下
200个消费者太多了。这反而会使它变慢,因为您有200个消费者在争夺消息。相反,尝试找到更接近cpu内核等的较低余额。
JMS客户端通常也有一个预取缓冲区(或类似的概念),这意味着消费者可能会预下载1000条消息,然后其他199个消费者无法处理这些消息。所以你也需要调整这个选项。
此外,如果你有太多的消费者和远程网络连接,那么你就会对IO等过于喋喋不休。所以这一切都是关于根据用例进行调整。
spring-jms内置了一个线程池,可以根据负载自动增长/收缩,这可以解释为什么在没有调整的情况下开箱即用看起来更快。
编写这样的逻辑有点复杂,这还没有添加到sjms中。我创建了一个关于这个的票证https://issues.apache.org/jira/browse/CAMEL-14637
您可以与商业Camel支持取得联系,因为有些公司和顾问在JMS代理和Camel方面拥有丰富的经验,并将它们调整到非常高的性能。JVM、OS和硬件的设置都可以产生很大的不同。
而且我还发现了一篇关于这个话题的好文章https://dzone.com/articles/performance-tuning-ideas-for-apache-camel