我正在使用Camel JMS组件进行请求答复以与MQ进行通信。对于我的某些请求,我可以收到 n 条回复消息。如何汇总这些回复消息?
我曾考虑将聚合器模式与聚合策略一起使用,但由于无法确定可以回复的邮件数量,因此无法使用它。
社区可以帮助我了解正确的做法吗?我做了一些谷歌搜索,但找不到有用的东西。下面是我的示例路线代码
from("direct:"+routeName).routeId(routeName)
.setHeader("JMSCorrelationID", constant(UUID.randomUUID().toString()))
.circuitBreaker()
.resilience4jConfiguration()
.minimumNumberOfCalls(3)
.end()
.to(mqComponentBeanName+"://CAMELDEMO?exchangePattern=InOut&requestTimeout=10000&replyTo=CAMELDEMOREPLY")
.log("${body}")
.unmarshal(customerDetailsOutBound)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
System.out.println(exchange.getIn().getBody().toString());
}
})
.onFallback().process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
System.out.println("Store this message to backup");
}
})
.end();
期待从社区中获得一些好的见解。谢谢。
答案 0 :(得分:1)
消息流
CAMELDEMO
队列,并开始等待新队列CAMELDEMO_AGGREGATED_REPLY
上的一条已加总消息CAMELDEMO
上收到消息的组件,开始将响应发送到CAMELDEMOREPLY队列,并指示将发送多少响应CAMELDEMOREPLY
,对邮件进行汇总,然后将汇总的邮件发送到CAMELDEMO_AGGREGATED_REPLY
。CAMELDEMO_AGGREGATED_REPLY
上等待回复的第一条路线将获得汇总回复,接收一条消息并将其发回 原始路线已更新,可以在CAMELDEMO_AGGREGATED_REPLY
上等待回复
...
.to(mqComponentBeanName+"://CAMELDEMO?exchangePattern=InOut&requestTimeout=10000&
replyTo=CAMELDEMO_AGGREGATED_REPLY")
.log("${body}")
.unmarshal(customerDetailsOutBound)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
System.out.println(exchange.getIn().getBody().toString());
}
})
....
用于汇总邮件的第二条路线
from(mqComponentBeanName+"://CAMELDEMOREPLY?
exchangePattern=In&requestTimeout=10000)
.aggregate(header("JMSCorrelationID"), new MyAggregationStrategy())
.to(mqComponentBeanName+"://CAMELDEMO_AGGREGATED_REPLY?
exchangePattern=Out&requestTimeout=10000)
public final class MyCompletionStrategy implements AggregationStrategy {
@Override
public Exchange aggregate(Exchange oldExch, Exchange newExchange)
{
...
//Here you check your flag regarding the number of responses
// you were supposed to receive, and if it is met
// complete the aggregation by setting it to true
oldExch.setProperty(Exchange.AGGREGATION_COMPLETE_CURRENT_GROUP, true);
...
return oldExchange;
}
}
答案 1 :(得分:1)
我能够用一条路线解决此问题。解决方案可能不那么整洁,但可以有效地实现目标。我使用过loopDoWhile,并且在loopDoWhile内的处理器中,我正在使用简单的Java代码从队列中获取消息。
property1
处理器内的代码:
from("direct:"+routeName).routeId(routeName)
.setHeader("JMSCorrelationID", constant(UUID.randomUUID().toString()))
.circuitBreaker()
.resilience4jConfiguration()
.minimumNumberOfCalls(3)
.end()
.to(mqComponentBeanName+"://CAMELDEMO?exchangePattern=InOut&requestTimeout=10000&replyTo=CAMELDEMOREPLY")
.log("${body}")
.unmarshal(customerDetailsOutBound)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
System.out.println(exchange.getIn().getBody().toString());
int msgCount = getMsgCountfromFirstReposnse;
if (msgCount > 1) {
exchange.getIn().setHeader("COUNTER", 0);
exchange.getIn().setHeader("MSG_COUNT", msgCount-1);
exchange.setProperty("connectionFactory", connectionFactory);
}
}
})
.loopDoWhile(simple("${headers.COUNTER} != ${headers.MSG_COUNT}"))
.process(simpleJMSConsumerProcess)
.end().endCircuitBreaker()
.onFallback().process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
System.out.println("Store this message to backup");
}
})
答案 2 :(得分:0)
好的,传统的请求答复设计为只有1条答复消息。第一个回复到达后,等待响应的线程将停止侦听。
使用JMS相关ID(每个请求没有专用线程),从理论上讲,有可能收到针对同一请求的多个答复,但我不知道JMS是否确实有效/允许。
根据评论进行更新
您在评论中写道,您可以收到一个请求的多个JMS答复,甚至可以得到期望的答案数量。
如果这一切都行得通,您可以在骆驼路线中使用Aggregator EIP收集所有回复,然后再将回复发送给呼叫者。
聚合器是高度可配置的。您可以决定如何组合响应,还可以定义多个完成条件(超时,消息数等)。