规则引擎(Apache camel) 学习五

1.Recipient List 接收者列表

   介绍:怎么使用条件判断向若干可能的路由路径中的某一条路径传送消息。

           那么如何做到根据判断条件,向若干可能的路径中的其中多条路径传送同一条消息呢?

           又或者向若干条可能的路径全部传输同一条消息呢?

          在Camel中可能被选择的消息路由路径称为接收者,Camel提供了多种方式向路由中可能成为下一处理元素的多个接收者发送消息:

          静态接收者列表(Static Recipient List)、动态接收者列表(Dynamic Recipient List)和 循环动态路由(Dynamic Router)。

         下面我们对这几种接收者列表形式进行逐一讲解。

 

2.使用multicast处理Static Recipient List

    介绍:使用multicast方式时,Camel将会把上一处理元素输出的Exchange复制多份发送给这个列表中的所有接收者,

              并且按顺序逐一执行(可设置为并行处理)这些接收者。这些接收者可能是通过Direct连接的另一个路由,

             也可能是Processor或者某个单一的Endpoint。需要注意的是,Excahnge是在Endpoint控制端点和Processor处理器间

             或者两个Processor处理器间唯一能够有效携带Message的元素,所以将一条消息复制多份并且让其执行不相互受到影响,

             那么必然就会对Exchange对象进行复制(是复制,是复制,虽然主要属性内容相同,但是这些Exchange使用的内存区域

             都是不一样的,ExchangeId也不一样)

      代码:

          以下是multicast使用的简单示例代码

              package com.yinwenjie.test.cameltest.helloworld;

                 ......

                 /**
                   * 测试组播路由
                   * @author yinwenjie
                   */
                   public class MulticastCamel extends RouteBuilder {

                       public static void main (String[] args) throws Exception {
                       // 这是camel上下文对象,整个路由的驱动全靠它了。
                       ModelCamelContext camelContext = new DefaultCamelContext ();
                        // 启动route
                       camelContext.start();
                       // 将我们编排的一个完整消息路由过程,加入到上下文中
                       camelContext.addRoutes (new MulticastCamel());

                       // 通用没有具体业务意义的代码,只是为了保证主线程不退出
                      synchronized (MulticastCamel.class) {
                               MulticastCamel.class.wait();
                                }
                      }

                      @Override
                      public void configure() throws Exception {
                            // 这个线程池用来进行multicast中各个路由线路的并发执行
                            ExecutorService executorService = Executors.newFixedThreadPool(10);
                            MulticastDefinition multicastDefinition = from("jetty: http://0.0.0.0:8282/multicastCamel") .multicast();

                            // multicast 中的消息路由可以顺序执行也可以并发执行
                            // 这里我们演示并发执行
                            multicastDefinition .setParallelProcessing(true);
                            // 为并发执行设置一个独立的线程池
                             multicastDefinition.setExecutorService (executorService);

                            // 注意,multicast中各路由路径的Excahnge都是基于上一路由元素的excahnge复制而来
                            // 无论前者Excahnge中的Pattern如何设置,其处理结果都不会反映在最初的Excahnge对象中
                           multicastDefinition.to("log:helloworld1? showExchangeId=true","log:helloworld2? showExchangeId=true")                       
                          // 一定要使用end,否则OtherProcessor会被做为multicast中的一个分支路由
                           .end()
                          // 所以您在OtherProcessor中看到的Excahnge中的Body、Header等属性内容
                          // 不会有“复制的Exchange”设置的任何值的痕迹
                          .process(new OtherProcessor());
                     }

                     /**
                       * 另一个处理器
                       * @author yinwenjie
                        */
                       public class OtherProcessor implements Processor {
                             /* (non-Javadoc)
                              * @ see org.apache.camel.Processo #process (org.apache.camel.Exchange)
                               */
                               @Override
                              public void process (Exchange exchange) throws Exception {
                                      Message message = exchange.getIn();
                                      LOGGER.info(" OtherProcessor中的exchange" + exchange);
                                      String body = message.getBody().toString();

                                      // 存入到exchange的out区域
                                      if(exchange.getPattern() == ExchangePattern.InOut) {
                                               Message outMessage = exchange.getOut();
                                               outMessage.setBody (body + " || 被OtherProcessor处理");
                                       }
                               }
                          }
                  }

          总结:

                以上代码片段中,我们使用multicast将原始的Exchange复制了多份,分别传送给multicast中的两个接收者,

                并且为了保证两个接收者的处理过程是并行的,我们还专门为multicast设置了一个线程池(不设置的话Camel将自行设置)。

                在以上的代码片段中,在multicast路由定义之后我们还设置了一个OtherProcessor处理器,

                它主要作用就是查看OtherProcessor中的Exchange对象的状态。下面的截图展示了以上代码片段的执行效果:

                

                总结:

                      通过执行结果可以看到,在multicast中的两个接收者(两个路由分支的设定)分别在我们设置的线程池中运行,

                      线程ID分别是【pool-1-thread-7】和【pool-1-thread-8】。在multicast中的所有路由分支都运行完成后,

                      OtherProcessor处理器的实例在【qtp1060925979-18】线程中继续运行(jetty:http-endpint对于本次请求的处理原本就在这个线程上运行)。

                      请各位读者特别注意以上三句日志所输出的ExchangeId,它们是完全不同的三个Exchange实例!

                     其中在multicast的两个路由分支中承载Message的Excahnge对象,它们的Exchange-ID号分别为

                    【ID-yinwenjie-240-54110-1466755310568-0-20】和【ID-yinwenjie-240-54110-1466755310568-0-19】,

                      来源则是multicast对原始Exchange对象的复制,原始Exchagne对象的Exchange-ID为【ID-yinwenjie-240-54110-1466755310568-0-16】。

 

 学习来源:http://www.uml.org.cn/zjjs/201801222.asp?artid=20340

posted @ 2020-08-26 14:08  小窝蜗  阅读(714)  评论(0编辑  收藏  举报