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

 更新时间:2019年03月13日 14:25:19   作者:双斜杠少年  
今天小编就为大家分享一篇关于Drools Fusion(CEP)定义及使用方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

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

定义

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

  • 通常需要处理巨量的事件,但是只有少部分事件是真正关心的。
  • 事件通常是不变的,因为它们是状态改变的一条记录。
  • 通常有关事件的规则和查询必须是运行在被动模式(reactive modes),即,对事件模式(patterns)的检测作出反应。
  • 通常在相关的事件之间有强烈的时间关系。
  • 个别事件通常是不重要的。系统关心相关事件的模式(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

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

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

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

@expires

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

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

使用如下

    @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 内的平均年龄

滑动长度窗口

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

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

例如年领大于49岁的最近两条记录

调用代码:

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

只匹配符合规则的最近的两条记录,所以舍弃“白展堂记录”

执行结果

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 等关键字 都是用于比较两个事件的发生时间顺序,用法待以后再叙

总结

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

相关文章

  • spring cloud实现前端跨域问题的解决方案

    spring cloud实现前端跨域问题的解决方案

    这篇文章主要介绍了 spring cloud实现前端跨域问题的解决方案,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • Centos6.5下Jdk+Tomcat+Mysql环境安装图文教程

    Centos6.5下Jdk+Tomcat+Mysql环境安装图文教程

    这篇文章主要为大家详细介绍了Centos6.5系统下Jdk+Tomcat+Mysql环境安装过程,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Jasypt的StandardPBEByteEncryptor使用源码解析

    Jasypt的StandardPBEByteEncryptor使用源码解析

    这篇文章主要介绍了Jasypt的StandardPBEByteEncryptor使用源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • java中&与&&的区别

    java中&与&&的区别

    本文主要介绍了java中&与&&的区别,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • RabbitMQ的基础知识

    RabbitMQ的基础知识

    本文详细介绍了RabbitMQ的基础知识,通过本文,我们可以了解到MQ工作原理、交换机等相关知识,有需要的朋友可以参考一下
    2021-08-08
  • 使用SpringBoot设置虚拟路径映射绝对路径

    使用SpringBoot设置虚拟路径映射绝对路径

    这篇文章主要介绍了使用SpringBoot设置虚拟路径映射绝对路径的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Spring Boot的Profile配置详解

    Spring Boot的Profile配置详解

    本篇文章主要介绍了Spring Boot的Profile配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • Java 中的5个代码性能提升技巧

    Java 中的5个代码性能提升技巧

    这篇文章主要给大家分享了Java的5个代码性能提升的技巧,虽然大多数情况下极致优化代码是没有必要的,但是作为一名技术开发者,我们还是想追求代码的更小、更快,更强。如果哪天发现程序的运行速度不尽人意,就需要这样的文章了,需要的朋友可以参考一下
    2021-12-12
  • Mybatis mapper标签中配置子标签package的坑及解决

    Mybatis mapper标签中配置子标签package的坑及解决

    这篇文章主要介绍了Mybatis mapper标签中配置子标签package的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java创建多线程的两种方式对比

    Java创建多线程的两种方式对比

    在Java中创建线程的方式有两种,第一种是直接继承Thead类,另一种是实现Runable接口。那么这两种方式孰优孰劣呢?这就是本文需要探讨的内容范畴了,看官们请仔细向下看
    2014-10-10

最新评论