Apache camel Camel:是否可以实现请求/回复&;借助异步处理器与消费者竞争?

Apache camel Camel:是否可以实现请求/回复&;借助异步处理器与消费者竞争?,apache-camel,Apache Camel,我正在努力实现一个请求/回复交换,该交换应该由几个竞争消费者同时处理 我有一个独立的主模块,负责生成任务队列。我有许多Worker模块,它们应该同时使用来自该队列的消息 这是驼峰路线的主部分: from(“直接:开始”) .to(“日志:从.DIRECT?级别=调试”) .split(body()).setHeader(CamelHeader.TASKS\u BATCH\u ID,简单(“BATCH-1”)) .setHeader(CamelHeader.TASK_类型,简单(TaskType.

我正在努力实现一个请求/回复交换,该交换应该由几个竞争消费者同时处理

我有一个独立的主模块,负责生成任务队列。我有许多Worker模块,它们应该同时使用来自该队列的消息

这是驼峰路线的主部分:

from(“直接:开始”)
.to(“日志:从.DIRECT?级别=调试”)
.split(body()).setHeader(CamelHeader.TASKS\u BATCH\u ID,简单(“BATCH-1”))
.setHeader(CamelHeader.TASK_类型,简单(TaskType.FETCH_索引))
.进程(新处理器(){
@凌驾
公共作废进程(Exchange)引发异常{
EdgarFullIndexLocation位置=
exchange.getIn().getBody(EdgarFullIndexLocation.class);
exchange.getIn().setBody(location.getId().toJson(),String.class);
}
})
.to(“日志:拆分?级别=调试”)
.setExchangePattern(ExchangePattern.InOut)
.to(“activemq:queue:tasksQueue?replyTo=completionsQueue”+
//“&TransactiveOut=true”+
“&requestTimeout=“+Integer.MAX_值”+
“&disableTimeToLive=true”)
.螺纹(10)
.to(“日志:响应?级别=调试”)
.routeId(routeId);
这是驼峰路由的工作者部分,在这里我使用队列:

from(“activemq:queue:tasksQueue?asyncConsumer=true”+
“&concurrentConsumers=10”)
.to(“日志:从.TASKS.QUEUE?级别=调试”)
.choice()
.when(头(CamelHeader.TASK_TYPE).isEqualTo(TaskType.FETCH_INDEX))
.process(新的FetchIndexTaskProcessor())
.否则()
.to(“log:UNKNOWN.TASK?level=DEBUG”);
这里的FetchIndexTaskProcessor实现了AsyncProcessor

公共类FetchIndexTaskProcessor实现异步处理器{
@重写公共无效进程(Exchange)引发异常{}
@凌驾
公共布尔进程(Exchange、异步回调){
FetchIndexTask任务=新建FetchIndexTask(交换、回调);
task.start();
返回false;
}
}
这里,FetchIndexTask扩展了线程。在start()之后,新线程负责:

  • 动态添加路由
  • 阻塞,直到该路由的交换完成
  • 准备对原始交换的答复
  • 调用
    callback.done(false)在末尾
  • 一切都正常,除了有竞争性消费者的部分——每次都是单一消费者

    我尝试了许多选择,如:

    • 在不同位置指定具有
      .threads(10)
      的线程池
    • 使用端点选项,如
      asyncConsumer
      concurrentConsumers

    但我似乎错过了一些重要的东西,而且我似乎无法让它同时工作。正确的方法是什么?

    如果您使用Camel 2.9或更高版本,那么我建议在执行请求/回复的activemq端点上使用replyToType=Exclusive。这告诉Camel队列是独占的,并且它会加速,因为不需要JMS消息选择器来拾取预期的相关消息

    请参阅驼峰JMS文档中的“通过JMS进行请求回复”部分:

    如果您使用临时队列,那么这也很快,因为不需要JMS消息选择器

    此外,您的路线从直接终点开始。这是一个同步调用,因此调用方将等待/阻止,直到交换完成

    还可以将拆分器EIP配置为以并行模式运行,该模式将使用并发处理。如果你有一个大消息要分裂,那么考虑使用流媒体,它将按需拆分消息,而不是将整个消息内容加载到内存中。 无论如何,在这条路线上有很多事情要做。
    你能更准确地指出你有问题的地方吗?它使帮助变得更容易

    我曾尝试使用5.6-SNAPSHOT版本的ActiveMQ和新的目标选项,但在
    destination.consumer.dispatchAsync=true
    split(…).parallelProcessing()
    -就是这样!