我正在努力实施请求/回复交换,应由多个竞争消费者同时处理。
我有一个独立的 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()之后,新线程负责:
callback.done(false);
。一切正常,除了竞争消费者之外 - 它一次只是一个消费者。
我尝试了很多选项,如:
.threads(10)
的线程池。asyncConsumer
和concurrentConsumers
但似乎我错过了一些重要的东西,而我似乎无法让它同时发挥作用。这样做的正确方法是什么?
答案 0 :(得分:2)
如果您使用Camel 2.9或更高版本,那么我建议在您请求/回复的activemq端点上使用replyToType = Exclusive。这告诉Camel队列是独占的,并且它加速,因为不需要JMS消息选择器来拾取预期的相关消息。
请参阅Camel JMS文档中的 JMS请求回复部分:http://camel.apache.org/jms
如果您使用临时队列,那么这也很快,因为不需要JMS消息选择器。
此外,您的路线以直接端点开头。这是一个同步调用,因此调用者将等待/阻塞,直到Exchange完全完成。
此外,Splitter EIP可以配置为以并行模式运行,该模式将使用并发处理。如果你有一个要分割的大消息,那么考虑使用流式传输,它将按需分割消息,而不是将整个消息内容加载到内存中。
无论如何,路线上还有很多事情发生。 你能更准确地指出你遇到问题的地方吗?这使得帮助更容易。