我正在使用Camel Split组件进行并行处理来拆分整数的ArrayList。该列表中有700,000多个ID。我们的想法是每个ID都需要传递给XML生成器,然后插入到数据库表中。但是,我注意到,生成并传递回邮件正文中的Camel的XML似乎仍然存在。看起来它保持在消息体上,直到Split中的所有元素都完成处理。这意味着我将在内存中拥有700,000多个XML。有没有办法告诉Camel不要这样做?拆分工作人员完成工作后放弃?
我已尝试制作ID块并拆分每个块,允许拆分完成并释放内存。这里的问题是每个ID生成不同大小的XML。因此,如果我创建了10个ID的块,并且其中1个具有与之关联的非常大的XML,则我的线程池必须等待最大的ID完成,并且最终得到9个空闲线程。
答案 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}");