Apache camel 使用apachecamel进行请求-应答和分散聚集

Apache camel 使用apachecamel进行请求-应答和分散聚集,apache-camel,Apache Camel,我正在尝试构建一条路线,该路线将执行以下操作: 在中使用来自jms:sender的消息。我使用的是INOUTrequest-reply模式。JMSReplyTo=sender out 上述消息将路由到多个收件人,如中的jms:consumer1、中的jms:consumer2和中的jms:consumer3。它们都使用请求-应答模式。JMSReplyTo是按每个消费者指定的(在本例中,JMSReplyTo的顺序是jms:consumer1 out、jms:consumer2 out、jms:co

我正在尝试构建一条路线,该路线将执行以下操作:

  • 在中使用来自
    jms:sender的消息。我使用的是
    INOUT
    request-reply模式。
    JMSReplyTo=sender out
  • 上述消息将路由到多个收件人,如中的
    jms:consumer1、
    中的
    jms:consumer2和
    中的
    jms:consumer3。它们都使用请求-应答模式。
    JMSReplyTo
    是按每个消费者指定的(在本例中,
    JMSReplyTo
    的顺序是
    jms:consumer1 out、jms:consumer2 out、jms:consumer3 out
  • 我需要将所有回复汇总在一起,并将结果发送回
    jms:sender out
  • 我构建了一条类似于以下内容的路线:

    from("jms:sender-in")
        .to("jms:consumer1-in?exchangePattern=InOut&replyTo=queue:consumer1-out&preserveMessageQos=true")
        .to("jms:consumer2-in?exchangePattern=InOut&replyTo=queue:consumer2-out&preserveMessageQos=true")
        .to("jms:consumer3-in?exchangePattern=InOut&replyTo=queue:consumer3-out&preserveMessageQos=true");
    
    然后,我将回复发送回某个队列以收集和聚合:

    from("jms:consumer1-out?preserveMessageQos=true").to("jms:gather");
    from("jms:consumer1-out?preserveMessageQos=true").to("jms:gather");
    from("jms:consumer1-out?preserveMessageQos=true").to("jms:gather");
    from("jms:gather").aggregate(header("TransactionID"), new GatherResponses()).completionSize(3).to("jms:sender-out");
    
    为了模仿我的消费者的行为,我添加了以下路径:

    from("jms:consumer1-in").setBody(body());
    from("jms:consumer2-in").setBody(body());
    from("jms:consumer3-in").setBody(body());
    
    我遇到了一些问题:

  • 我在回复上收到超时错误。如果我注释掉收集部分,则没有问题。为什么即使回复返回到队列,然后转发到另一个队列,也会出现超时
  • 如何存储原始JMSReplyTo值,以便Camel能够将聚合结果发送回发送方的应答队列
  • 我有一种感觉,我正在与一些基本概念作斗争。任何帮助都将不胜感激。 谢谢。

    一个好问题

    有两件事你需要考虑

  • 不要将请求-应答(InOut)与事件混用 消息(仅限)。(除非您有充分的理由)
  • 如果你做了一件事,你需要提出请求 ,否则他们将是,而事实并非如此 真的
  • 我举了两个与您的案例类似的例子——一个是请求-回复,另一个是(单向)事件消息

    可以用jms替换activemq组件,在这些示例中也是如此

    示例一,使用事件消息-仅:

    from("activemq:amq.in")
        .multicast()
            .to("activemq:amq.q1")
            .to("activemq:amq.q2")
            .to("activemq:amq.q3");
    
    from("activemq:amq.q1").setBody(constant("q1")).to("activemq:amq.gather");
    from("activemq:amq.q2").setBody(constant("q2")).to("activemq:amq.gather");
    from("activemq:amq.q3").setBody(constant("q3")).to("activemq:amq.gather");
    
    from("activemq:amq.gather")
        .aggregate(new ConcatAggregationStrategy())
            .header("breadcrumbId")
            .completionSize(3)
            .to("activemq:amq.out");
    
    from("activemq:amq.out")
        .log("${body}"); // logs "q1q2q3"
    
    示例二,使用Request-reply-注意,散射路由必须在响应进入时收集响应。结果与第一个示例相同,但路由和配置更少

    from("activemq:amq.in2")
        .multicast(new ConcatAggregationStrategy())
            .inOut("activemq:amq.q4")
            .inOut("activemq:amq.q5")
            .inOut("activemq:amq.q6")
        .end()
        .log("Received replies: ${body}"); // logs "q4q5q6"
    
    from("activemq:amq.q4").setBody(constant("q4"));
    from("activemq:amq.q5").setBody(constant("q5"));
    from("activemq:amq.q6").setBody(constant("q6"));
    

    至于你的第二个问题——当然,可以绕过JMSReplyTo头并强制交换模式——但你会创建难以调试的代码。保持交换模式简单干净——这样可以避免bug。

    谢谢你详细的回答,佩特。我不知道我能做到这一点:
    。多播(新的ConcatAggregationStrategy())
    。这解决了眼前的问题。近5年后,这仍然是最好的答案!