Apache camel:路由中的多线程

时间:2014-03-21 19:27:39

标签: apache-camel

  

String processFiles =" file:// somedirectory?readLock = rename& preMove = inprogress /& move = .. / processed /& amp; moveFailed = .. / error /"

     

String postProcessor =" file:// somedirectory / inprogress&#34 ;;

     

从(processFiles)       .threads(10)       .routeId(" someId&#34)
      。为了("豆:somebean&#34);

     

从(后处理器)       .routeId(" postProcress&#34)       。为了("豆:postProcessorBean&#34);

使用多个线程从特定位置读取文件。然后处理在" somebean"。

中完成

现在,我希望在所有线程完成第一个路由后进行一些后期处理。 我不明白什么时候打电话给后处理器。 我上面的方法是给出不正确的结果。 PostProcessor在" Somebean"之前被调用。由所有线程完成。 我想知道一旦所有线程完成后我如何调用postProcess" somebean"

只是提出一个问题陈述: 1.我们有一些文件,每个文件在一个位置有数百万条记录。我们需要读取这些文件并将数据保存在数据库中。 2.在其他表中完成更新状态。

解决方案已经到位。但目前它需要更多时间。因此我们尝试在驼峰路由级别使用线程,以便可以同时处理多个文件。 现在,我们可以最小化时间但不能进行后处理(即步骤2)

2 个答案:

答案 0 :(得分:2)

使用聚合器模式:

from("file:src/main/resources/data/parallel-file-processing?noop=true")
    .threads(10)
    .process(new PreProcessor())
    .aggregate(constant(true), new ArrayListAggregationStrategy())
    .completionFromBatchConsumer()
    .process(new PostProcessor());

PreProcessor实现Processor接口,在10个独立的线程中完成耗时的工作人员。

预处理的结果与使用aggregate的{​​{1}}汇总,取自Camel聚合器doc

ArrayListAggregatorStrategy

//simply combines Exchange body values into an ArrayList<Object> public class ArrayListAggregationStrategy implements AggregationStrategy { public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { Object newBody = newExchange.getIn().getBody(); List<Object> list = null; if (oldExchange == null) { list = new ArrayList<Object>(); list.add(newBody); newExchange.getIn().setBody(list); return newExchange; } else { list = oldExchange.getIn().getBody(List.class); list.add(newBody); return oldExchange; } } } (或bean)收到可以进行后处理的PostProcessor

List

最后,后期处理也是并行完成的:

private static class PostProcessor implements Processor {
    @SuppressWarnings("unchecked")
    @Override
    public void process(final Exchange exchange) throws Exception {
        final Object body = exchange.getIn().getBody();
        final List<GenericFile<File>> list = (List<GenericFile<File>>) body;
        for (final GenericFile<File> genericFile : list) {
            LOG.info("file = " + genericFile.getAbsoluteFilePath());
        }
    }
}

答案 1 :(得分:1)

使用aggregator在一些可配置数量的消息或超时后重新加入