【问题标题】:apache camel - parallel processor then join outputapache camel - 并行处理器然后加入输出
【发布时间】:2019-07-15 11:22:37
【问题描述】:

我希望对两个处理器进行并行处理(从不同来源获取不同的信息),然后当两者都完成后,我希望能够访问两个输出以进行进一步处理(例如比较)。

类似的东西:

from("direct:start)
            .processor("process1")
            .processor("process2")
      .to("direct:compare");

除了我需要process1process2 的输出都可以在“比较”端点中使用。

【问题讨论】:

    标签: parallel-processing apache-camel spring-camel


    【解决方案1】:

    这是使用多播和聚合策略实现的一种方式,

    public class App {
      public static void main(String[] args) throws Exception {
    
        CamelContext context = new DefaultCamelContext();
        context.addRoutes(myRoute());
        context.startRoute("start");
        context.start();
        ProducerTemplate producerTemplate = context.createProducerTemplate();
        producerTemplate.sendBody("direct:start", null);
        Thread.sleep(10_000);
        context.stop();
    
      }
    
      private static RouteBuilder myRoute() {
        return new RouteBuilder() {
          @Override
          public void configure() throws Exception {
            from("direct:start").routeId("start")
                    .multicast(new MyAggregationStrategy())
                    .parallelProcessing()
                    .to("direct:process1", "direct:process2", "direct:process3")
                    .end()
            .to("direct:endgame");
    
            from("direct:process1")
                    .process(e -> {
                      ArrayList<String> body = Lists.newArrayList("a", "b", "c");
                      e.getIn().setBody(body);
                    });
    
            from("direct:process2")
                    .process(e -> {
                      ArrayList<String> body = Lists.newArrayList("1", "2", "3");
                      e.getIn().setBody(body);
                    });
    
            from("direct:process3")
                    .process(e -> {
                      ArrayList<String> body = Lists.newArrayList("@", "#", "$");
                      e.getIn().setBody(body);
                    });
    
    
            from("direct:endgame")
                    .process(e -> {
                      log.info(" This final result : " + e.getIn().getBody());
                    });
          }
        };
      }
    }
    
    //This is where we can aggregate results of the process which is running in parallel
    class MyAggregationStrategy implements AggregationStrategy {
    
      @Override
      public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        ArrayList<Object> objects = Lists.newArrayList();
        if (oldExchange == null) {
          return newExchange;
        }
    
        Object o = oldExchange.getIn().getBody();
        Object n = newExchange.getIn().getBody();
    
        objects.add(o);
        objects.add(n);
    
        newExchange.getIn().setBody(objects);
    
        return newExchange;
      }
    }
    

    【讨论】:

    • 您可以使用GroupedBodyAggregationStrategy 代替实现自定义
    • 也谢谢@Bedla,我已经使用了它。
    • @SunandPadmanabhan,所以我观察到这与“直接”一起工作得很好,但是当我改为“seda”时,因为预计会有多个生产者同时触发(他们应该都在每个自己的线程上运行),即使“process1/2/3”还没有完成他们的工作,也会立即调用“endgame”端点(使用零列表交换)。有什么想法吗?
    • 我不确定,我必须自己尝试一下。如果您可以粘贴您尝试实现的代码 sn-p 将会很有帮助。
    • @SunandPadmanabhan 这里是stackoverflow.com/questions/57087489/…
    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    相关资源
    最近更新 更多