从文件到持久JMS队列的路由:如何提高性能?

时间:2014-11-10 11:35:29

标签: elasticsearch apache-camel activemq

我需要一些用例性能调优方面的帮助。在此用例中,Camel路由在日志文件中拖尾状态行,并将每行作为消息发送到JMS队列。我已经实现了这样的用例:

package tests;

import java.io.File;
import java.net.URI;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.sjms.SjmsComponent;
import org.apache.camel.main.Main;

public class LinesToQueue {

    public static void main() throws Exception {

        final File file = new File("data/log.txt");
        final String uri = "tcp://127.0.0.1:61616";

        final BrokerService jmsService = BrokerFactory.createBroker(new URI("broker:" + uri));
        jmsService.start();

        final SjmsComponent jmsComponent = new SjmsComponent();
        jmsComponent.setConnectionFactory(new ActiveMQConnectionFactory(uri));

        final Main main = new Main();
        main.bind("jms", jmsComponent);
        main.addRouteBuilder(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                fromF("stream:file?fileName=%s&scanStream=true&scanStreamDelay=0", file.getAbsolutePath())
                        .routeId("LinesToQueue")
                        .to("jms:LogLines?synchronous=false");
            }
        });

        main.enableHangupSupport();
        main.run();
    }

}

当我使用已填充1.000.000行的文件运行此用例时,我在路径中获得的整体性能大约为313行/秒。这意味着处理文件大约需要55分钟。

作为某种参考,我也创建了另一个用例。在此用例中,Camel路由在日志文件中拖尾状态行,并将每行作为文档发送到Elasticsearch索引。我已经实现了这样的用例:

package tests;

import java.io.File;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.main.Main;

public class LinesToIndex {

    public static void main() throws Exception {

        final File file = new File("data/log.txt");
        final String uri = "local";

        final Main main = new Main();
        main.addRouteBuilder(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                fromF("stream:file?fileName=%s&scanStream=true&scanStreamDelay=0", file.getAbsolutePath())
                        .routeId("LinesToIndex")
                        .bean(new LineConverter())
                        .toF("elasticsearch://%s?operation=INDEX&indexName=log&indexType=line", uri);
            }
        });

        main.enableHangupSupport();
        main.run();
    }

}

当我使用已填充1.000.000行的文件运行此用例时,我在路径中获得的整体性能约为8333行/秒。这意味着处理文件大约需要2分钟。

我知道JMS队列和Elasticsearch索引之间存在巨大差异,但如何让上面的JMS用例表现更好?

更新#1:
似乎是JMS服务中的持久性是我上面第一个用例的瓶颈。如果我在JMS服务中禁用持久性,那么路由中的性能大约是11111行/秒。 JMS服务的哪种持久性存储会给我带来更好的性能?

1 个答案:

答案 0 :(得分:1)

要考虑的几件事情......

  • ActiveMQ制作人连接are expensive,请确保使用池化连接工厂......

  • 考虑将VM transport用于进程中的ActiveMQ实例

  • 考虑通过TCP使用外部ActiveMQ代理(因此它不会与您的测试竞争资源)

  • 设置/调整KahaDB或LevelDB以优化用例的持久存储