Apache Camel:完成后丢弃拆分处理器

时间:2014-03-27 02:53:06

标签: java multithreading split apache-camel

我正在使用Camel Split组件进行并行处理来拆分整数的ArrayList。该列表中有700,000多个ID。我们的想法是每个ID都需要传递给XML生成器,然后插入到数据库表中。但是,我注意到,生成并传递回邮件正文中的Camel的XML似乎仍然存在。看起来它保持在消息体上,直到Split中的所有元素都完成处理。这意味着我将在内存中拥有700,000多个XML。有没有办法告诉Camel不要这样做?拆分工作人员完成工作后放弃?

我已尝试制作ID块并拆分每个块,允许拆分完成并释放内存。这里的问题是每个ID生成不同大小的XML。因此,如果我创建了10个ID的块,并且其中1个具有与之关联的非常大的XML,则我的线程池必须等待最大的ID完成,并且最终得到9个空闲线程。

2 个答案:

答案 0 :(得分:0)

你签出了Splitter EIP reference on Streambased splitting吗?它似乎与您的问题直接相关。使用streaming()调用和自定义聚合器

可能会更好

我很冒险你正在经历拆分器聚合器的默认行为,它会从您传递拆分消息的任何处理器中获取所有“回复”,并将它们全部重新连接在一起以作为单个传递响应“从分离器处理器到您路径中的下一个处理器。因此,内存中的大型XML负载。

如果您编写自定义聚合器,则可以只记录编组和持久化的消息计数,并将其作为来自拆分器的“响应”传递,该响应应显式从内存中释放XML有效负载。我会给出一个更清晰的例子,但这些天我的骆驼很生锈。

我希望我在这里留下足够的面包屑来帮忙。很大程度上,看看我在本答案顶部链接的文档,有一些很好的样本似乎直接或几乎适用于您的用例。

答案 1 :(得分:0)

实际上,我不知道,如果这是最佳做法,但是如果不再需要身体内容,你可以定义一个Processor清空身体,如下所示:

 public class EmptyProcessor implements Processor {
     @Override
     public void process(final Exchange exchange) throws Exception {
         exchange.getIn().setBody(null);
     }
 }

此外,您可以并行处理单个拆分,因此持久作业不会阻止处理。

示例路线:

final Random random = new Random(3);

from("direct:start")
    .split().method(Splitter.class, "split")  // the splitter creates the Integer list
    .parallelProcessing()
    .executorService(Executors.newFixedThreadPool(2))
    .process(new Processor() {
        @Override
        public void process(final Exchange exchange) throws Exception {
            final long waitMs = (long) (random.nextFloat() * 1000);
            System.out.println("Doing a long lasting job for " + waitMs + " ms");
            Thread.sleep(wait);
        }
    })
    .process(new EmptyProcessor())
    .log("Body (should be emtpy): ${body}");