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

总结

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

(0)

相关推荐

  • SpringBoot2整合Drools规则引擎及案例详解

    一.Drools引擎简介 1.基础简介 Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效.具有易于访问企业策略.易于调整以及易于管理的特点,作为开源业务规则引擎,符合业内标准,速度快.效率高. 2.规则语法 (1).演示drl文件格式 package droolRule ; import org.slf4j.Logger import org.slf4j.Logge

  • SpringBoot2.0整合jackson配置日期格式化和反序列化的实现

    网上杂七杂八的说法不一,大多数都是抄来抄去,没有实践,近期在项目频繁遇到boot+jackson处理日期的问题,故开此贴. 首先是POM <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance

  • SpringBoot整合Elasticsearch7.2.0的实现方法

    Spring boot 2.1.X整合Elasticsearch最新版的一处问题 新版本的Spring boot 2的spring-boot-starter-data-elasticsearch中支持的Elasticsearch版本是2.X,但Elasticsearch实际上已经发展到7.2.X版本了,为了更好的使用Elasticsearch的新特性,所以弃用了spring-boot-starter-data-elasticsearch依赖,而改为直接使用Spring-data-elastics

  • Spring Boot+Drools规则引擎整合详解

    目的 官方的Drools范例大都是基于纯Java项目或Maven项目,而基于Spring Boot项目的很少. 本文介绍如何在Spring Boot项目上加上Drools规则引擎. POM依赖 POM文件如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=&q

  • springboot整合H2内存数据库实现单元测试与数据库无关性

    一.新建spring boot工程 新建工程的时候,需要加入JPA,H2依赖 二.工程结构 pom文件依赖如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:s

  • Spring Boot整合Swagger2的完整步骤详解

    前言 swagger,中文"拽"的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅, 而且还提供了在线文档的测试.另外swagger很容易构建restful风格的api. 一.Swagger概述 Swagger是一组围绕OpenAPI规范构建的开源工具,可帮助设计.构建.记录和使用REST API. 简单说下,它的出现就是为了方便进行测试后台的restful形式的接口,实现动态的更新,当我们在后台的接口 修改了后,swagger可以实现自动的更新,而不需要

  • springboot2.0整合dubbo的示例代码

    写在前面: 使用springboot作为web框架,方便开发许多,做分布式开发,dubbo又不可少,那么怎么整合在一起呢, 跟我学一遍,至少会用 注意,springboot2.0和springboot1.x与dubbo整合不一样, 1.环境 1.新建一个空的maven项目,作为父工程,新建moudle,,service(接口层,及实现层,没有具体分,),web(web层,springboot项目) 项目结构如下 父pom如下 <properties> <project.build.sou

  • SpringBoot2.0整合SpringCloud Finchley @hystrixcommand注解找不到解决方案

    hystrix参数使用方法 通过注解@HystrixCommand的commandProperties去配置, 如下就是hystrix命令超时时间命令执行超时时间,为1000ms和执行是不启用超时 @RestController public class MovieController { @Autowired private RestTemplate restTemplate; @GetMapping("/movie/{id}") @HystrixCommand(commandPro

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

    从 Drools 统一行为建模平台的视野看,Drools Fusion 是负责启用事件处理行 为的一个模块. 定义 支持复杂事件处理,是比简单的理解事件是什么要更多得多,cep场景具有几个共同而明显的特点: 通常需要处理巨量的事件,但是只有少部分事件是真正关心的. 事件通常是不变的,因为它们是状态改变的一条记录. 通常有关事件的规则和查询必须是运行在被动模式(reactive modes),即,对事件模式(patterns)的检测作出反应. 通常在相关的事件之间有强烈的时间关系. 个别事件通常是

  • PHP的Yii框架中行为的定义与绑定方法讲解

    定义行为 要定义行为,通过继承 yii\base\Behavior 或其子类来建立一个类.如: namespace app\components; use yii\base\Behavior; class MyBehavior extends Behavior { public $prop1; private $_prop2; public function getProp2() { return $this->_prop2; } public function setProp2($value)

  • C语言深入讲解宏的定义与使用方法

    目录 一.C语言中的宏定义 二.宏定义表达式 三.宏表达式与函数的对比 四.有趣的问题 五.强大的内置宏 六.小结 一.C语言中的宏定义 #define是预处理器处理的单元实体之一 #define 定义的宏可以出现在程序的任意位置 #define 定义之后的代码都可以使用这个宏 #define 定义的宏常量可以直接使用 #define 定义的宏常量本质为字面量 下面的宏常量定义正确吗? 编写代码来测试: #define ERROR -1 #define PATH1 "D:\test\test.c

  • Python数据结构之双向链表的定义与使用方法示例

    本文实例讲述了Python数据结构之双向链表的定义与使用方法.分享给大家供大家参考,具体如下: 和单链表类似,只不过是增加了一个指向前面一个元素的指针而已. 示意图: python 实现代码: #!/usr/bin/python # -*- coding: utf-8 -*- class Node(object): def __init__(self,val,p=0): self.data = val self.next = p self.prev = p class LinkList(obje

  • C语言预处理器使用方法讲解

    目录 预处理器实例 预定义宏 预处理器运算符 参数化的宏 C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤.简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理.我们将把 C 预处理器(C Preprocessor)简写为 CPP. 所有的预处理器命令都是以井号(#)开头.它必须是第一个非空字符,为了增强可读性,预处理器指令应从第一列开始.下面列出了所有重要的预处理器指令: 预处理器实例 分析下面的实例来理解不同的指令. #defin

  • AngularJS中控制器函数的定义与使用方法示例

    本文实例讲述了AngularJS中控制器函数的定义与使用方法.分享给大家供大家参考,具体如下: HTML正文: <body ng-app="myApp" ng-controller="myCtrl"> <h2>AngularJS函数绑定</h2> <textarea ng-model="message" cols="40" rows="10"></tex

  • PHP字典树(Trie树)定义与实现方法示例

    本文实例讲述了PHP字典树(Trie树)定义与实现方法.分享给大家供大家参考,具体如下: Trie树的概念(百度的解释):字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高. 我的理解是用来做字符串搜索的,每个节点只包含一个字符,比如录入单词"world",则树的结构

  • PHP完全二叉树定义与实现方法示例

    本文实例讲述了PHP完全二叉树定义与实现方法.分享给大家供大家参考,具体如下: 若设二叉树的深度为h,除第 h 层外,其它各层 (1-h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树. PHP代码实现(暂时实现添加节点.层次遍历节点,删除节点后续更新) <?php class Node{ public $value; public $leftNode; public $rightNode; } /* 找到空节点 */ function findEmpyt

  • JS类的定义与使用方法深入探索

    本文实例分析了JS类的定义与使用方法.分享给大家供大家参考,具体如下: js可以定义自己的类 很有意思 <script type="text/javascript"> var Anim = function() { alert('nihao'); }; Anim.prototype.start = function() { alert('start'); }; Anim.prototype.stop = function() { alert('stop'); }; var

  • javascript中定义类的方法汇总

    JS中定义类的方式有很多种: 1.工厂方式 复制代码 代码如下: function Car(){    var ocar = new Object;    ocar.color = "blue";    ocar.doors = 4;    ocar.showColor = function(){     document.write(this.color)    };    return ocar;   }   var car1 = Car();   var car2 = Car()

随机推荐