骆驼JMS请求-“ n”答复消息答复

时间:2020-06-22 04:15:32

标签: apache-camel ibm-mq camel-jms

我正在使用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();

期待从社区中获得一些好的见解。谢谢。

3 个答案:

答案 0 :(得分:1)

消息流

  1. 您的第一条路线将消息发送到CAMELDEMO队列,并开始等待新队列CAMELDEMO_AGGREGATED_REPLY上的一条已加总消息
  2. CAMELDEMO上收到消息的组件,开始将响应发送到CAMELDEMOREPLY队列,并指示将发送多少响应
  3. 下面的第二条路线开始侦听CAMELDEMOREPLY,对邮件进行汇总,然后将汇总的邮件发送到CAMELDEMO_AGGREGATED_REPLY
  4. 您在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收集所有回复,然后再将回复发送给呼叫者。

聚合器是高度可配置的。您可以决定如何组合响应,还可以定义多个完成条件(超时,消息数等)。