骆驼:是否有可能实施请求/回复&在异步处理器的帮助下竞争消费者?

时间:2012-04-10 08:18:16

标签: apache-camel

我正在努力实施请求/回复交换,应由多个竞争消费者同时处理。

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

这是Camel路由的 Master - 部分:

from("direct:start")
.to("log:FROM.DIRECT?level=DEBUG")
.split(body()).setHeader(CamelHeader.TASKS_BATCH_ID, simple("BATCH-1"))
.setHeader(CamelHeader.TASK_TYPE, simple(TaskType.FETCH_INDEX))
.process(new Processor() {
    @Override
    public void process(Exchange exchange) throws Exception {
        EdgarFullIndexLocation location = 
            exchange.getIn().getBody(EdgarFullIndexLocation.class);
        exchange.getIn().setBody(location.getId().toJson(), String.class);
    }
})
.to("log:SPLIT?level=DEBUG")
.setExchangePattern(ExchangePattern.InOut)
.to("activemq:queue:tasksQueue?replyTo=completionsQueue" +
    //"&transactedInOut=true" + 
    "&requestTimeout=" + Integer.MAX_VALUE +
    "&disableTimeToLive=true")
.threads(10)
.to("log:RESPONSE?level=DEBUG")
.routeId(routeId);

这是我使用队列的Camel路由的 Worker 部分:

from("activemq:queue:tasksQueue?asyncConsumer=true" + 
    "&concurrentConsumers=10")
.to("log:FROM.TASKS.QUEUE?level=DEBUG")
.choice()
    .when(header(CamelHeader.TASK_TYPE).isEqualTo(TaskType.FETCH_INDEX))
        .process(new FetchIndexTaskProcessor())
    .otherwise()
        .to("log:UNKNOWN.TASK?level=DEBUG");

此处 FetchIndexTaskProcessor 实现 AsyncProcessor

public class FetchIndexTaskProcessor implements AsyncProcessor {
    @Override public void process(Exchange exchange) throws Exception {}

    @Override
    public boolean process(Exchange exchange, AsyncCallback callback) {
        FetchIndexTask task = new FetchIndexTask(exchange, callback);
        task.start();
        return false;
    }

}

此处 FetchIndexTask 扩展线程。在 start()之后,新线程负责:

  1. 动态添加路线。
  2. 阻止直到该路线的交换完成。
  3. 准备回复原始交易所。
  4. 最后致电callback.done(false);
  5. 一切正常,除了竞争消费者之外 - 它一次只是一个消费者。

    我尝试了很多选项,如:

    • 在不同的地方指定一个.threads(10)的线程池。
    • 使用端点选项,例如asyncConsumerconcurrentConsumers

    但似乎我错过了一些重要的东西,而我似乎无法让它同时发挥作用。这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

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

请参阅Camel JMS文档中的 JMS请求回复部分:http://camel.apache.org/jms

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

此外,您的路线以直接端点开头。这是一个同步调用,因此调用者将等待/阻塞,直到Exchange完全完成。

此外,Splitter EIP可以配置为以并行模式运行,该模式将使用并发处理。如果你有一个要分割的大消息,那么考虑使用流式传输,它将按需分割消息,而不是将整个消息内容加载到内存中。

无论如何,路线上还有很多事情发生。 你能更准确地指出你遇到问题的地方吗?这使得帮助更容易。