Apache camel 有可能在驼峰路线上有一个拆分池吗

Apache camel 有可能在驼峰路线上有一个拆分池吗,apache-camel,Apache Camel,我正在使用拆分器拆分一个大文件,对拆分进行一些处理,然后使用自定义聚合策略将更新的拆分保存到一个新文件中。拆分器配置为流式处理,但不是并行处理。这个很好用 问题是拆分器调用了同步的doAggregate(继承自MulticastProcessor)。当该路由上存在并发请求时,同步会显著影响性能。显然,并发请求越多,情况就越糟 是否有方法创建可用于路由的拆分器实例池?每个传入的交换都可以使用不同的拆分器实例,从而避免同步的doAggregate调用。是否可以利用自定义ProcessorFactor

我正在使用拆分器拆分一个大文件,对拆分进行一些处理,然后使用自定义聚合策略将更新的拆分保存到一个新文件中。拆分器配置为流式处理,但不是并行处理。这个很好用

问题是拆分器调用了同步的doAggregate(继承自MulticastProcessor)。当该路由上存在并发请求时,同步会显著影响性能。显然,并发请求越多,情况就越糟

是否有方法创建可用于路由的拆分器实例池?每个传入的交换都可以使用不同的拆分器实例,从而避免同步的doAggregate调用。是否可以利用自定义ProcessorFactory来执行此操作

更新:

我创建了一个简单的测试来演示我所说的内容。 我有一条这样的路线

from("direct:splitterTest").split(method(new MySplitter(), "rowIterator"), new MyAggregationStrategy()).to("log:someSplitProcessing?groupSize=500")
MySplitter只返回一个10000字符串[]的迭代器,该迭代器模拟读取文件

MyAggregationStrategy假装执行一些工作,并将记录保存到新文件中。 在我的测试中,我添加了循环来模拟一些处理,比如

Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < 10000; i++) {
    random.nextGaussian();
}
Random Random=new Random(System.currentTimeMillis());
对于(int i=0;i<10000;i++){
random.nextGaussian();
}
我像这样向路由提交请求(在这种情况下,我不是在传递文件,因为拆分器只是返回虚拟数据):

ProducerTemplate ProducerTemplate=camelContext.createProducerTemplate();
Future future1=producerTemplate.asyncRequestBody(“direct:splitterTest”,null,File.class);
Future future2=producerTemplate.asyncRequestBody(“direct:splitterTest”,null,File.class);
System.out.println(future1.get());
System.out.println(future2.get());
我想发布visualvm屏幕截图,显示2和4个并发的飞行中交换是如何受到同步的影响的,但是这个帐户太新了,不允许发布图像

关键是这一点。创建路由时,该路由只有一个拆分器实例。该路由上的多个空中交换将在DOAGGRAGATE呼叫中同步,这将严重影响每个请求的处理时间。当有4个请求时,您可以看到3个线程被阻塞,而一个线程在doAggregate调用中


由于我正在进行的处理的性质,我无法将拆分器配置为并行处理,因此我正在寻找一种创建多个拆分器实例的方法。比如说,我可以创建4个路由副本,然后使用routingSlip或dynamicRouter将请求循环发送给每个人,但这似乎有点难看,我希望有更好的方法。

如果您想从doAggregate并行保存,您可以使用自己的线程池。

您是否控制拆分器上的线程池?请发一些代码。我也有类似的问题,但通过使用线程池,我能够限制线程的数量,从而优化拆分器的运行。我没有在拆分器中使用线程池(本身),因为它不是并行运行的(我需要按顺序处理行,所以并行对我来说不是一个好选择)。但是,对路由的提交使用异步调用,该调用通过带有线程池的生产者模板进行,请求在这些线程上运行。但问题是,定义路由时,会创建一个拆分器实例。所有doAggregate调用(即使它们可能在不同的线程上针对不同的文件运行)都是同步的。然而,ProducerTemplate有一个线程池,并且在路由上并发运行多个请求。处理器的实际拆分和调用在多个核上并发运行,直到到达doAggregate调用为止,没有任何问题。
ProducerTemplate producerTemplate = camelContext.createProducerTemplate();
Future<File> future1 = producerTemplate.asyncRequestBody("direct:splitterTest", null, File.class);
Future<File> future2 = producerTemplate.asyncRequestBody("direct:splitterTest", null, File.class);
System.out.println(future1.get());
System.out.println(future2.get());