1. Drools Fusion(CEP)定义及使用方法讲解

     更新时间:2019年03月13日 14:25:19   作者:双?#22791;?#23569;年   我要评论

    今天小编就为大家分享一篇关于Drools Fusion(CEP)定义及使用方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    从 Drools 统一行为建模平台的视野看,Drools Fusion 是负责启用事件处理行 为的一个模块。

    定义

    支持复杂事件处理,是比简单的理解事件是什么要更多得多,cep场景具有几个共同而明显的特点:

    • 通常需要处理巨量的事件,但是只有少部分事件是真正关心的。
    • 事件通常是不变的,因为它们是状态改变的一条记录。
    • 通常有关事件的规则和查询必须是运行在被动模式(reactive modes),即,对事件模式(patterns)的检测作出?#20174;Α?/li>
    • 通常在相关的事件之间有强烈的时间关系。
    • 个别事件通常是不重要的。系统关心相关事件的模式(patterns)和它们的关系
    • 通常,要求系统执行组合和聚合的事件。

    用fusion,要把插入drools的数据声明为事件。

    drools处理数据有两种方式,云模式和流模式,默认是云模式,用fusion,需要设置为流模式。流模式,插入的数据叫事件,有时间顺序,云模式没有,

    流(stream)支持

    大部分 CEP 用例必须处理事件流(stream)。

    流的特性:

    • 在流中的事件通过时间戳被排序。
    • 事件的数量(volumes)总是很高的。
    • 原子事件自己是很少有用的。通常根据多个事件之间的相关性或流或其他来源提取含义。
    • 流可以是相似的,即包含单一类型的事件;或者是异类的,即包含多种类型的事件。

    声明流模式

    在kmodule.xml 中添加配置 eventProcessingMode=“stream” 为流模式

    <kbase name="fusionAge" eventProcessingMode="stream" packages="com.us.fusion">
        <ksession name="fusionAgeKS" type="stateful"/>
    </kbase>

    事件声明

    用fusion,要把插入drools的数据声明为事件,声明事件使用@role标签

    @role

    把@role元数据标签指派给该事实类行

    例如:

    Person 为java bean 也就是一个事实类型

    declare Person
      @role(event)
    end

    Person 的属性如下:

    public class Person {
      private String name;
      private Integer age;
      private String like;
      private String sex;
      private String desc;
      private String address;
      private Date createTime;
      // getter setter 省略

    @timestamp

    每一个事件?#23478;?#26377;一个关联的时间戳指派给它。默认时,一个给定事件的时间戳是在事件被插入到工作内存时,从 Session Clock 读取,并且分配给该事件。有些时候,事件用时间戳作为它自己的一个属性。在这情况下,用户可以用@timestamp 标记用户属性为时间戳

    例如:用Person的 createTime 属性为时间戳

    declare Person
      @role(event)
      @timestamp( createTime )
    end

    @expires

    重要:这个标签只有引擎运行在流(STREAM)模式之下才会被考虑.

    该标签显示定义 一个事件在什?#35789;?#20505;应该到期,事件到期,事件可能不再匹配和激活任何规则时。

    使用如下

        @expires( 1h35m )

    在person 例子中假设过期时间为20S

    declare Person
      @role(event)
      @timestamp( createTime )
      @expires(20s)
    end

    滑动时间窗口

    滑动时间窗口允许用户编写规则,其将仅匹配在最近的 X 时间单元内发生的事件

    rule "boy"
       when
          $p : Person(age < 25) over window:time(3s)
       then
          $p.setDesc("少年");
          retract($p);
    end

    例如:只匹配最近3秒内,年龄小于25的人

    调用代码如下:

    package com.us.fusion;
    import com.us.model.Person;
    import org.kie.api.KieServices;
    import org.kie.api.runtime.KieContainer;
    import org.kie.api.runtime.KieSession;
    import java.util.Date;
    /**
     * Created by yangyibo on 17/1/3.
     * @author yangyibo
     */
    public class Application {
      private static KieSession getSession() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kc = ks.getKieClasspathContainer();
        return kc.newKieSession("fusionAgeKS");
      }
      public static void run() {
        KieSession ks = getSession();
        Person p1 = new Person("白展堂", 2,new Date());
        Person p2 = new Person("佟湘玉", 7,new Date());
        try {
          Thread.sleep(4000);
        } catch (InterruptedException e) {
          System.out.println(e);
        }
        Person p3 = new Person("李大嘴", 16,new Date());
        ks.insert(p1);
        ks.insert(p2);
        ks.insert(p3);
        int count = ks.fireAllRules();
        System.out.println("总执行了" + count + "条规则------------------------------");
    //    ks.dispose();
      }
      public static void main(String[] args) {
        run();
      }
    }

    规则代码如下:

    package com.us.fusion7
    import com.us.model.Person
    function void printName(String streamName,String name,int age,String desc) {
          System.out.println("streamName:"+streamName+" name:"+name+" age:"+age+" desc:"+ desc);
        }
    declare Person
      @role(event)
      @timestamp( createTime )
      @expires(20s)
    end
    rule "boy"
       when
          $p : Person(age > 0) over window:time(3s)
       then
          $p.setDesc("少年");
          retract($p);
          printName("boy",$p.getName(),$p.getAge(),$p.getDesc());
    end

    由于Thread.sleep(4000);所以最近3秒内只有李大嘴一条记录所以

    结果如下:

    streamName:boy  name:李大嘴 age:16 desc:少年
    总执行了1条规则------------------------------

    范例2 10S 内的平均年龄

    滑动长度窗口

    和滑动时间窗口很类似,其将仅匹配最近?#22797;?#21457;生的事件,用法如图,只匹配最近1次发生的事件。

    rule "old"
       when
          $p : Person(age > 49) over window:length(2)
       then
          $p.setDesc("老年");
          retract($p);
    end

    例如年领大于49岁的最近?#25945;?#35760;录

    调用代码:

    public class Application {
      private static KieSession getSession() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kc = ks.getKieClasspathContainer();
        return kc.newKieSession("fusionAgeKS");
      }
      public static void run() {
        KieSession ks = getSession();
        Person p1 = new Person("白展堂", 52,new Date());
        Person p2 = new Person("佟湘玉", 57,new Date());
        try {
          Thread.sleep(4000);
        } catch (InterruptedException e) {
          System.out.println(e);
        }
        Person p3 = new Person("李大嘴", 56,new Date());
        ks.insert(p1);
        ks.insert(p2);
        ks.insert(p3);
        int count = ks.fireAllRules();
        System.out.println("总执行了" + count + "条规则------------------------------");
        ks.dispose();
      }
      public static void main(String[] args) {
        run();
      }
    }

    规则代码

    package com.us.fusion7
    import com.us.model.Person
    function void printName(String streamName,String name,int age,String desc) {
          System.out.println("streamName:"+streamName+" name:"+name+" age:"+age+" desc:"+ desc);
        }
    declare Person
      @role(event)
      @timestamp( createTime )
      @expires(20s)
    end
    rule "old"
       when
          $p : Person(age > 49) over window:length(2)
       then
          $p.setDesc("老年");
          retract($p);
          printName("boy",$p.getName(),$p.getAge(),$p.getDesc());
    end

    只匹配符合规则的最近的?#25945;?#35760;录,所以舍弃“白展堂记录”

    执行结果

    streamName:boy  name:李大嘴 age:56 desc:老年
    streamName:boy  name:佟湘玉 age:57 desc:老年
    总执行了2条规则------------------------------

    本文所有测试例子的pom 依赖

        <dependency>
          <groupId>org.kie</groupId>
          <artifactId>kie-api</artifactId>
          <version>6.5.0.Final</version>
        </dependency>
        <dependency>
          <groupId>org.drools</groupId>
          <artifactId>drools-core</artifactId>
          <version>6.5.0.Final</version>
        </dependency>
        <dependency>
          <groupId>org.drools</groupId>
          <artifactId>drools-compiler</artifactId>
          <version>6.5.0.Final</version>
        </dependency>
        <dependency>
          <groupId>org.drools</groupId>
          <artifactId>drools-decisiontables</artifactId>
          <version>6.5.0.Final</version>
        </dependency>
        <dependency>
          <groupId>org.drools</groupId>
          <artifactId>drools-templates</artifactId>
          <version>6.5.0.Final</version>
        </dependency>

    本文所有测试例子的kmodule.xml 配置

     <kbase name="fusionAge" eventProcessingMode="stream" packages="com.us.fusion">
        <ksession name="fusionAgeKS" type="stateful"/>
     </kbase>

    其他关键字: After, Before, During, Meet 等关键字 都是用于比较两个事件的发生时间顺序,用法待以后再叙

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

    相关文章

    • Java中的值传递和引用传递实例介绍

      Java中的值传递和引用传递实例介绍

      java 中没有引用传递,都是值传递的,可以通过传递副本修改对象的,副本交换,并不影响原引用
      2013-09-09
    • java实现输入输出流代码分享

      java实现输入输出流代码分享

      这篇文章主要介绍了java实现输入输出流代码分享的相关资料,需要的朋友可以参考下
      2015-09-09
    • 详解MyEclipse中搭建spring-boot+mybatis+freemarker框架

      详解MyEclipse中搭建spring-boot+mybatis+freemarker框架

      这篇文章主要介绍了详解MyEclipse中搭建spring-boot+mybatis+freemarker框架,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
      2017-10-10
    • 利用solr实现商品的搜索功能(实例讲解)

      利用solr实现商品的搜索功能(实例讲解)

      下面小编就为大家分享一篇利用solr实现商品的搜索功能,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
      2017-11-11
    • ?#31243;?#24322;常结构图、编译期异常和运行期异常的区别

      ?#31243;?#24322;常结构图、编译期异常和运行期异常的区别

      下面小编就为大家带来一篇?#31243;?#24322;常结构图、编译期异常和运行期异常的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
      2016-09-09
    • java字符串切割实例学习(获取文件名)

      java字符串切割实例学习(获取文件名)

      在Java中处理一些路径相关的问题的时候,如要取出ie浏览器上传文件的文件名,由于ie会把整个文件路径都作为文件名上传,需要用java.lang.String中的replaceAll或者split来处理,下面看看使用方法
      2013-12-12
    • Java随机数算法原理与实现方法实例详解

      Java随机数算法原理与实现方法实例详解

      这篇文章主要介绍了Java随机数算法原理与实现方法,简单分析了随机数算法的原理并结合具体实例形式给出了java编程计算随机数的具体操作?#35760;?需要的朋友可以参考下
      2017-09-09
    • Java 基础详解(泛型、集合、IO、反射)

      Java 基础详解(泛型、集合、IO、反射)

      下面小编就为大家带来一篇Java 基础详解(泛型、集合、IO、反射)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
      2017-10-10
    • Spring Boot JPA访问Mysql示例

      Spring Boot JPA访问Mysql示例

      本篇文章主要介绍了Spring Boot JPA访问Mysql示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
      2017-03-03
    • Java中对于双属性枚举的使用案例

      Java中对于双属性枚举的使用案例

      今天小编就为大家分享一篇关于Java中对于双属性枚举的使用案例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
      2018-12-12

    最新评论

    山东群英会开奖查询