drools 决策引擎介绍、开发

1. 背景介绍

1.1  何为规则引擎

很多企业的IT业务系统中,经常会有大量的业务规则配置,而且随着企业管理者的决策变化,这些业务规则也会随之发生更改,为了适应这样的需求,IT业务系统应该能够快速且低成本的更新,通常做法是将业务规则的配置单独拿出来,使之与业务系统保持低耦合,实现这样功能的程序,叫做规则引擎。

接受数据输入,解释业务规则,并根据业务规则作出业务决策,从而实现了将业务决策从应用程序中分离出来。

1.2  一个实际的例子

银行贷款业务中,每种贷款类型都有不同的业务规则,并且这些规则也可能会根据实际应用情况进行调整,如觉得网贷产品类型有如下判定规则:

  • 如果公积金缴存基数大于6000则进入白领贷
  • 如果公积金缴存基数小于6000但单位性质是国家机关/事业单位也进入白领贷
  • 如果公积金缴存基数小于6000且单位性质为非国家机关/事业单位则进入市民易贷
  • 如果公积金缴存基数小于6000并且单位性质缺失则进入公积金贷

如果在代码中处理这类业务逻辑,会有很多的IF/ELSE,并且如果规则发生变化,还需要重新编写代码、编译、部署才能上线。

而通过规则引擎,可以方便的将这类业务强相关的逻辑放到规则引擎中执行

1.3  规则引擎的优点

对系统的使用人员

l  把业务策略(规则)的创建、修改和维护的权利交给业务经理

l  提高业务灵活性

l  加强业务处理的透明度,业务规则可以被管理

l  减少对IT人员的依赖程度

l  避免升级的风险

IT开发人员

l  简化系统架构,优化应用

l  提高系统的可维护性和维护成本

l  方便系统的整合

l  减少编写“硬代码”业务规则的成本和风险

2. Drools简介

Drools是一款基于Java的开源规则引擎,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件或特定的数据库中,使得业务规则的变更不需要修改代码即可在线上环境生效。

规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用代码中分离出来,并使用预定义的语义模块编写业务决策。接收数据输入,解释业务规则,并根据业务规则作出业务决策。

3. Drools基本概念

3.1  工作流程

需要判定的规则加载进ProductionMemory

需要判定的fact对象插入到WorkingMemory

推理引擎(Inference Engine)通过模式匹配器(Pattern Matcher)对规则和fact对象进行批评,如果有规则匹配成功,则将待执行的规则放入Agenda(议事日程)队列中等待执行。

当Agenda队列中的规则执行的过程中如果对WorkingMemory中的Fact对象进行了insert/update/delete操作时,需要重新进行推理判定,刷新Agenda队列中的执行序列。

当Agenda队列中所有规则执行完毕后,结束当前任务。

3.2  Fact对象

Fact对象指传递给Drools脚本的对象,是一个普通的POJO,可以对该Fact对象进行读写操作,并调用该对象的方法。

当一个POJO插入到WorkingMemory中变成Fact之后,Fact对象不是对原来POJO对象进行Clone,而是对原有对象的引用。规则通过对fact对象的读写,实现对应用数据的读写,对其中的属性,需要提供get/set方法,通过这些getter 和setter 方法可以方便的实现对Fact 对象的读写操作,所以我们可以简单的把Fact 对象理解为规则与应用系统数据交互的桥梁或通道。

规则中可以动态的在WorkingMemory中插入删除新的fact对象。

3.3  Rete算法简介

Rete算法是Charles Forgy博士在1979年的论文中首次提出的,针对基于规则知识表现的模式匹配算法。当前,大部分规则引擎都是基于Rete算法为核心。

Rete算法是一个用于产生式系统的高效模式匹配算法。在一个产生式系统中,被处理的数据叫做WorkingMemory,用于判定的规则分为两个部分LHS(left-hand-side)和RHS(right hand side),分别表示前提和结论。主要流程可以分为以下步骤:

  • Match:找出符合LHS部分的WorkingMemory集合
  • Confilict resolution:选出一个条件被满足的规则
  • Act:执行RHS的内容
  • 返回第一步

Rete算法主要改进Match的处理过程,通过构建一个网络进行匹配。

3.4  基础语法

Drools文件中最重要的是:包路径、引用、规则体

一个DRL文件的例子HelloWorld.drl

package:包路径。该路径是逻辑路径,可以随便写,但不能不写,已.的方式隔开,规则文件中永远是第一行

import:引用。导入规则文件需要使用到的外部变量,可以导入类,也可以是类中的静态方法

rule:规则体。以rule开头,以end结尾,每个文件可以包含多个rule,规则体分为3个部分:LHS、RHS、属性。

LHS:(Left Hand Side),条件部分,在一个规则当中”when”和”then”中间的部分就是LHS部分,在LHS当中,可以包含0~N个条件,如果LHS为空的话,那么引擎会自动添加一个eval(true)的条件。

RHS:(Right Hand Side),是规则真正做事情的部分,满足条件触发动作的操作部分,在RHS中可以使用LHS部分当中定义的绑定变量名、设置的全局变量、或者是直接编写的java代码,也可以使用import的类,虽然可以,但不建议在RHS中有条件判断。

RHS中可以使用insert/update/modify/delete实现对当前WorkingMemory中Fact对象的新增/修改/删除。

3.5  KIE API

3.5.1什么是KIE

KIE是jBoss里面一些相关项目的统称,下图就是KIE代表的一些项目,其中我们比较熟悉的就有jBPM和Drools。

jBPM:工作流引擎

Drools:规则引擎

OptaPlanner:规划引擎

Guvnor:业务规划管理系统(Drools 6.0后已被WorkBench替换)

这些项目都有一定的关联关系,并且存在一些通用的API,比如说涉及到构建(building)、部署(deploying)和加载(loading)等方面的,这些API就都会以KIE作为前缀来表示这些是通用的API。

总的来说,就是jBoss通过KIE将jBPM和Drools等相关项目进行了一个整合,统一了他们的使用方式。像KieServices这些KIE类就是整合后的结果,在Drools中这样使用,在jBPM里面也是这样使用。

在Drools当中,规则的编译与运行要通过Drools提供的各种API来实现,这些API总体来讲可以分为三类:规则编译、规则收集和规则执行。完成这些工作的API主要有KnowledgeBuilder、KnowledgeBase、StatefulKnowledgeSession、StatelessKnowledgeSession等,它们起到了对规则文件进行收集、编译、查错、插入fact、设置global、执行规则或规则流等作用。

3.5.2 KnowledgeBuilder

KnowledgeBuilder的作用是用来在业务代码当中收集已经编写好的规则,然后对这些规则文件进行编译,最终产生一批编译好的规则包(KnowledgePackage)给其他的应用程序使用。

KnowledgeBuilder在编译规则的时候可以通过其提供的hasErrors()方法得到编译规则过程中发现规则是否有错误,如果有的话通过其提供的getErrors()方法将错误打印出来,以帮助我们找到规则当中的错误信息。

通过KnowledgeBuilder编译的规则文件的类型有很多种,如.drl文件或一个xls文件等。产生的规则包可以是具体的规则文件行程的,也可以是规则流(rule flow)文件形成的,在添加规则文件时,需要通过使用ResourceType枚举值来指定规则文件的类型;同时在指定规则文件的时候drools还提供了一个名为ResourceFactory的对象,通过该对象可以实现从Classpath、URL、File、ByteArray、Reader或诸如XLS的二进制文件里加载规则。

3.5.3 KnowledgeBase

KnowledgeBase是Drools提供的用来收集应用当中知识(Knowledge)定义的知识库对象,在一个KnowledgeBase当中可以包含普通的规则(rule)、规则流(rule flow)、函数定义(function)、用户自定义的对象(type model)等。

业务对象都是插入到由KnowledgeBase产生的两种类型的session 对象当中(StatefulKnowledgeSession 和StatelessKnowledgeSession,后面会有对应的章节对这两种类型的对象进行介绍),通过session 对象可以触发规则执行或开始一个规则流执行。

KnowledgeBase 创建完成之后,接下来就可以将我们前面使用KnowledgeBuilder 生成的KnowledgePackage 的集合添加到KnowledgeBase 当中。

3.5.4 StatefulKnowledgeSession

StatefulKnowledgeSession 对象是一种最常用的与规则引擎进行交互的方式,它可以与规则引擎建立一个持续的交互通道,在推理计算的过程当中可能会多次触发同一数据集。接收外部插入的数据fact对象(POJO),将编译好的规则包和业务数据通过fireAllRules()方法触发所有的规则执行。使用完成需调用dispose()方法以释放相关内存资源。

3.5.5 StatelessKnowledgeSession

对StatefulKnowledgeSession的封装实现,与其对比不需要调用dispose()方法释放内存,只能插入一次fact对象,StatelessKieSession隔离了每次与规则引擎的交互,不会维护会话状态。

4. Drools详细介绍

4.1  Drl

在Drools当中,一个标准的规则文件就是一个以”.drl”结尾的文本文件,由于它是一个标准的文本文件,所以可以通过一些记事本工具对其进行打开、查看和编辑。规则是放在规则文件当中的,一个规则文件可以存放多个规则,除此之外,在规则文件当中还可以存放用户自定义的函数、数据对象及自定义查询等相关在规则当中可能会用到的一些对象。

一个标准的规则文件的结构代码:

package package-name(包名,必须的,用于逻辑上的管理,若自定义查询或函数属于同一个包名,不管物理位置如何,都可以调用),package在规则文件中是第一行,其他的顺序可以是无序的

import(需要导入的类名)

globals(全局变量)

functions(函数)

queries(查询)

rules(规则,可以多个)

一个规则包含三部分:只有attributes部分可选,其他都是必填

4.1.1 属性attributes

定义当前规则执行的一些属性等,比如是否可被重复执行,过期时间,生效时间等。

Salience 优先级

作用:设置规则执行的优先级,值是一个数字,数字越大执行的优先级越高,它的值可以是一个负数,默认值是0。如果我们不手动设置salience属性值,则执行顺序是随机的。

no-loop 防止死循环

在一个规则中如果条件满足就对Working Memory当中的某个Fact对象进行修改,比如使用update将其更新到当前的Working Memory当中,这时候引擎会再次检查所有的规则是否满足条件,如果满足会再执行,可能会出现死循环。

作用:用来控制已经执行过的规则条件再次满足时是否再次执行,默认是false,如果属性值是true,表示该规则只会被规则引擎检查一次。

lock-on-active 规则执行一次

当在规则上使用ruleflow-group属性或agenda-group属性的时候,将lock-on-active属性的值设置为true,可以避免因某些Fact对象被修改而使已经执行过的规则再次被激活执行。可以看出该属性与no-loop属性有相似之处,no-loop属性是为了避免Fact修改或调用了insert,retract,update之类导致规则再次激活执行,这里lock-on-active属性也是这个作用,lock-on-active是no-loop的增强版。

作用:在使用ruleflow-group属性或agenda-group属性的时候,默认是false,设置为true,该规则只会执行一次。

ruleflow-group 规则流分组

在使用规则流的时候要用到ruleflow-group属性,该属性的值为一个字符串,作用是将规则划分为一个个的组,然后在规则流当中通过使用ruleflow-group属性的值,从而使用对应的规则。该属性会通过流程的走向确定要执行哪一条规则。

4.1.2 LHS

定义当前规则的条件,如 when Message();判断当前workingMemory中是否存在Message对象。

LHS部分是由一个或多个条件组成,条件又称为pattern(匹配模式),多个pattern之间可以使用 and 或 or来进行连接,同时还可以使用小括号来确定pattern的优先级

【绑定变量名:】Object(【filed 约束】)

对于一个pattern来说"绑定变量名"是可选的,如果在当前规则的LHS部分的其他pattern要使用这个对象,那么可以通过为该对象绑定设定一个绑定变量名来实现对其的引用,对于绑定变量的命名,通常的做法是为其添加一个 "$"符号作为前缀,可以和Fact对象区分开来。

绑定变量可以用于对象上,可以用于对象属性上,"field约束"是指当前对象里相关字段的条件限制。

以上,

第一个pattern有三个约束

1、对象类型必须是Customer;

2、Customer的age要大于20

3、Customer的gender要是male

第二个pattern有三个约束

  1、对象类型必须是Order

  2、Order对应的Customer必须是前面那个Customer

  3、当前这个Order的price要大于1000

这两个pattern没有符号连接,在Drools当中没有连接符号,默认是and,只有两个pattern(模式)都满足才会返回true。

4.1.3 RHS

RHS是满足LHS条件之后进行后续处理部分的统称,该部分包含要执行的操作的列表信息。RHS主要用于处理结果,因此不建议在此部分再进行业务判断。

RHS的主要功能是对working memory中的数据进行insert、update、delete或modify操作,Drools提供了相应的内置方法来帮助实现这些功能。

RHS中可以写java代码,即当前规则条件满足执行的操作,可以直接调用Fact对象的方法来操作应用。

4.1.4 Function函数

函数是将语义代码放置在规则文件中的一种方式,就相当于java类中的方法一样。使用函数的好处是可以将业务逻辑集中放置在一个地方,根据需要可以对函数进行修改。

4.2  决策表

决策表是一个”精确而紧凑的”表示条件逻辑的方式,非常适合商业级别的规则。目前决策表支持xls格式和csv格式。

4.2.1 何时使用决策表

如果规则能够被表达为模板+数据的格式,可以考虑使用决策表。

决策表中的每一行就是对应一行数据,将产生一个规则。

4.2.2 运行决策表

首先,决策表将转换为Drools规则语言(DRL),然后执行规则引擎需求。

4.2.3 决策表的配置

全局配置:

RuleTable部分

4.2.4 决策表例子

年龄分类规则如下:

决策表设计:

POJO对象:

测试类:

结果:

4.3  规则流

4.3.1 什么是规则流

规则流能够控制,规则中的复杂流程,在复杂业务中,很多时候并不需要触发所有的规则,很多时候需要触发的规则也需要像程序一样,符合某些逻辑,如,当X对象X 属性等于 A 时,触发 规则A 中的规则,当等于B时,触发规则B中的规则,这时候用规则流就能够很好的处理这类问题。

4.3.2 如何使用规则流

创建规则流文件如score.bpmn

指定规则文件相关属性:

流程中指定,评分模型的规则组:

设置网关判定条件:

编辑各条网关连接线的判断依据:

4.3.3 规则流组件

RuleTask

规则任务,可和规则文件中指定规则组关联

ScriptTask

脚本任务,可编写脚本完成指定任务

Gateway

按网关方向可分为聚合网关diverging gateway和分散网关converging gateway

按网关类型可分为:

u  唯一网关XOR网关

唯一网关会选择一个顺序流, 如果条件执行为true。如果多个条件 执行为true,第一个遇到的就会被使用。

u  并行网关AND网关

l  并行网关拥有一个进入顺序流的和多于一个的外出顺序流 叫做‘并行切分或 ‘AND-split‘。所有外出顺序流都会 被并行使用。

l  并行网关拥有多个进入顺序流和一个外出顺序流 叫做‘并行归并‘或 AND-join。所有进入顺序流需要 到达这个并行归并,在外向顺序流使用之前。

u  包含网关OR网关

包含网关先后执行为true的分支。

5. 开发环境搭建

5.1安装Drools插件

5.1.1 下载Drools插件

可以去工具集中下载

5.1.2 安装Drools插件

Help->Install New Software

重启Eclipse,如果Preferences中出现Drools则说明插件安装成功。

5.2安装Drools Runtimes(Drools运行时)

5.2.1下载Drools Engine

5.2.2在Eclipse中指定Drools Runtimes

Windows->Preferences->Drools->Installed Drools Runtimes

可以新建Drools项目

6. Drools代码编写注意事项

6.1规则流部分

  • 每个flow需要有至少一个进入点(Start Event)和一个退出点(End Event)
  • 网关按方向有diverge(分离网关)和converge(汇聚网关),需要合理使用
  • 网关按类型有唯一网关(XOR)、并行网关(AND)和包含网关(OR),需要合理使用
  • 唯一网关(XOR)作为分离网关,会选择外出的多个顺序流中的一个
  • 并行网关(AND)作为分离网关,拥有一个进入顺序流和多个外出顺序流,叫做“并行切分(AND-split)”,所有的外出顺序流都会被执行
  • 并行网关(AND)作为汇聚网关,拥有多个进入顺序流和一个外出顺序流,叫做“并行归并(AND-join)”,所有进入顺序流都需要到达并行网关,才会执行外出顺序流
  • 包含网关(OR)基本行为和唯一网关类似,区别在于,满足条件的外出顺序流都会被执行
  • Id唯一的代表一个flow元素,不能重复
  • 界面创建flow元素后自动生成的MetaData的UniqueId需要检查不能以数字开头,否则调用规则流引擎时会报错
  • 如果规则流需要引用WorkingMemory中的Fact对象,需要在规则流的Properties中定义Variables,此变量需要在Java代码调用规则流时作为参数传入

6.2决策表部分

  • 合理设置RuleSet名称,确保不重复
  • 决策表编写需注意格式,如CONDINTION下第四行是第一条数据(规则)配置行
  • CONDITION和ACTION中都可以使用匹配Fact变量的成员函数
  • ACTION中更新WorkingMemory中Fact对象后需考虑是否规则是否会反复触发导致死循环
  • 如果想规则始终进入,可使用eval(true)
  • CONDITION中如果使用可能会变化的Fact对象的Map中的value,需要使用原生的get方法
  • CONDITION中使用占位符匹配规则时,如果是字符串需要用双引号引起来

6.3 Java代码部分

  • 需要使用session的insert方法将需要处理的对象插入到WorkingMemory
  • 如果规则流需要使用Fact对象,需要在调用规则流的时候将Fact对象放入map中,作为参数传入
  • 启用规则流后,还需要调用session的fireAllRules才会执行匹配的规则

有状态session使用后必须显式调用dispose方法来释放,避免内存

原文地址:https://www.cnblogs.com/renfeihn/p/11857235.html

时间: 2024-10-09 00:53:20

drools 决策引擎介绍、开发的相关文章

drools规则引擎因为内存泄露导致的内存溢出

进入这个问题之前,先了解一下drools: 在很多行业应用中比如银行.保险领域,业务规则往往非常复杂,并且规则处于不断更新变化中,而现有很多系统做法基本上都是将业务规则绑定在程序代码中. 主要存在的问题有以下几个方面: 1) 当业务规则变更时,对应的代码也得跟着更改,每次即使是小的变更都需要经历开发.测试验证上线等过程,变更成本比较大. 2) 长时间系统变得越来越难以维护. 3) 开发团队一般是由一个熟悉业务的BA(业务分析人员)和若干个熟悉技术的开发人员组成,开发人员对业务规则的把握能力远不及

第1部分: 游戏引擎介绍, 渲染和构造3D世界

原文作者:Jake Simpson译者: 向海Email:[email protected] ------------------------------------------------------------第1部分: 游戏引擎介绍, 渲染和构造3D世界 介绍 自Doom游戏时代以来我们已经走了很远. DOOM不只是一款伟大的游戏,它同时也开创了一种新的游戏编程模式: 游戏 "引擎". 这种模块化,可伸缩和扩展的设计观念可以让游戏玩家和程序设计者深入到游戏核心,用新的模型,场景和

mysql 存储引擎介绍

一  存储引擎解释 首先确定一点,存储引擎的概念是MySQL里面才有的,不是所有的关系型数据库都有存储引擎这个概念,后面我们还会说,但是现在要确定这一点. 在讲清楚什么是存储引擎之前,我们先来个比喻,我们都知道录制一个视频文件,可以转换成不同的格式,例如mp4,avi,wmv等,而存在我们电脑的磁盘上也会存在于不同类型的文件系统中如windows里常见的ntfs.fat32,存在于linux里常见的ext3,ext4,xfs,但是,给我们或者用户看懂实际视频内容都是一样的.直观区别是,占用系统的

实时智能决策引擎在蚂蚁金服风险管理中的实践

摘要:以"数字金融新原力(The New Force of Digital Finance)"为主题,蚂蚁金服ATEC城市峰会于2019年1月4日上海如期举办.金融智能专场分论坛上,蚂蚁金服数据技术专家王修坤做了主题为<实时智能决策引擎在蚂蚁金服风险管理中的实践>的精彩分享.在演讲中,王修坤分享了互联网保险产品场景化.高频化和碎片化的典型特征以及在风险控制方面所面临的诸多挑战,并为大家介绍了实时智能决策引擎在蚂蚁金服风险管理中的实践.王修坤 蚂蚁金服保险事业群数据技术专家

MySQL存储引擎介绍 w

一 存储引擎解释 首先确定一点,存储引擎的概念是MySQL里面才有的,不是所有的关系型数据库都有存储引擎这个概念,后面我们还会说,但是现在要确定这一点. 在讲清楚什么是存储引擎之前,我们先来个比喻,我们都知道录制一个视频文件,可以转换成不同的格式,例如mp4,avi,wmv等,而存在我们电脑的磁盘上也会存在于不同类型的文件系统中如windows里常见的ntfs.fat32,存在于linux里常见的ext3,ext4,xfs,但是,给我们或者用户看懂实际视频内容都是一样的.直观区别是,占用系统的空

几款java工作流程引擎快速开发平台比较

相对传统代码开发,快速开发平台在开发周期.成本上以及扩展性方面都有非常大的优势.如果每个项目都要从零开始,代码无复用率:所有的基础功能需要一行一点的敲代码,开发效率非常低,所以使用传统的开发工具已经不能满足现有程序员的诉求,越来越多的企业和开发人员选择java快速开发平台.为了更好地帮助大家找到适合自己的流程引擎, 快速地完成流程引擎技术架构选型, 快速地完成项目交付.下面一起来看看几款java工作流引擎快速开发平台. 希望您能从中找到适合您自己的流程引擎.ActivitiActiviti是由j

js模板引擎介绍搜集

js模板引擎越来越多的得到应用,如今已经出现了几十种js模板引擎,国内各大互联网公司也都开发了自己的js模板引擎(淘宝的kissy template,腾讯的artTemplate,百度的baiduTemplate等),如何从这么多纷繁的模板引擎中选择一款适合自己的呢,笔者最近对主流的js模板引擎(mustache,doT,juicer,artTemplate,baiduTemplate,Handlebars,Underscore)做了一番调研,分享出来希望对大家有用. 从这几个指标来比较js模板

【课程下载】基于Cocos2d-x游戏引擎实战开发炸弹超人

我这里有套课程想和大家分享,需要的朋友可以加我qq和我联系.QQ2059055336. 课程讲师:Jason.Z 课程分类:ios适合人群:初级课时数量:31课时更新程度:完毕 一.本课程是怎么样的一门课程(全面介绍) 1.1.课程的背景 Cocos2d-x 是一个支持多平台的 2D 手机游戏引擎,使用 C++ 开发,基于OpenGL ES,基于Cocos2d-iphone,支持 WOPhone, iOS 4.1, Android 2.1 及更高版本, WindowsXP & Windows7,

浏览器渲染引擎介绍(备忘)

Trident.Gecko.Presto.WebKit --是4种常见的浏览器内核(1)Trident 是微软的Windows搭载的网页浏览器--Internet Explorer浏览器使用的内核(俗称IE内核)(2)Gecko Gecko是开放源代码.以C++编写的网页排版引擎,目前被Mozilla家族网页浏览器以及Netscape 6以后版本浏览器所使用. 也就是现在的Firefox(3)Presto Presto是一个由Opera Software开发的浏览器排版引擎,目前Opera 7.