1.规则引擎
规则引擎是由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。开源的代表是Drools,商业的代表是Visual Rules ,I Log
复杂企业级项目运营及维护过程中随外部条件不断变化的业务规则(business logic),
迫切需要分离商业决策者的商业决策逻辑和应用开发者的技术决策,
并把这些商业决策放在中心数据库或其他统一的地方,让它们能独立运行;可以动态地管理和修改规则模板从而提供软件系统的柔性和适应性
2.Drools规则引擎
Drools具有一个易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。
Drools是为Java量身定制的基于Charles Forgy的RETE算法的规则引擎的实现。支持Java代码直接嵌入到规则文件中,使得商业规则有了更自然的表达。
Drools主要分为两个部分:一是Drools规则,二是Drools规则的解释执行。规则的编译与运行要通过Drools 提供的相关API 来实现。而这些API 总体上游可分为三类:规则编译、规则收集和规则的执行
3.Drools规则引擎优点
3.1申明式编程
明确规则机制让我们可以“做什么”
规则机制的核心优势在于可以简化对于复杂问题的逻辑表述,并对这些逻辑进行验证。
规则机制提供一个如何解决问题的说明,并说明每个决策的是如何得出的
3.2业务逻辑和数据分离
业务数据存储业务对象中,业务决策存储规则中,独立运行
3.3速度和可扩展性
使用网络算法(Rete algorithm),跳跃算法(Leaps algorithm),提供了非常高效的方式根据业务对象的数据匹配规则
3.3.1 Rete算法
Rete算法是一个快速的模式匹配算法,它通过存储关于规则的信息而获得速度
Rete算法的基本思想是保存过去匹配过程中留下的全部信息,以空间代价来换取执行效率 。对每一个模式 ,附加一个匹配元素表来记录WorkingMemory中所有能与之匹配的元素。当一个新元素加入到WorkingMemory时, 找出所有能与之匹配的模式, 并将该元素加入到匹配元素表中; 当一个无素从WorkingMemory中删除时,同样找出所有与该元素匹配的模式,并将元素从匹配元素表中删除。 Rete算法接受对工作存储器的修改操作描述 ,产生一个修改冲突集的动作
Rete的高效率主要来自两个重要的假设
时间冗余性:facts在推理过程中的变化是缓慢的, 即在每个执行周期中,只有少数的facts发生变化,因此影响到的规则也只占很小的比例。所以可以只考虑每个执行周期中已经匹配的facts.
结构相似性:许多规则常常包含类似的模式和模式组。
Rete算法的步骤如下:
1.将初始数据(fact)输入Working Memory。
2.使用Pattern Matcher比较规则(rule)和数据(fact)。
3.如果执行规则存在冲突(conflict),即同时激活了多个规则,将冲突的规则放入冲突集合。
4.解决冲突,将激活的规则按顺序放入Agenda。
5.使用规则引擎执行Agenda中的规则。
重复步骤2至5,直到执行完毕所有Agenda中的规则
3.3.2 Leaps 算法
前向推理引擎,包括LEAPS,都包括了匹配-选择-执行(match-select-action)循环。即,确定可以匹配的规则,选择某个匹配 的元 组,此元组相应的规则动作被执行。重复这一过程,直到某一状态(如没有更多的规则动作)。RETE和TREAT匹配算法速度慢的原因是,它们把满足规则条 件的元组都实例化。Leaps算法的最大的改进就是使用一种"lazy"的方法来评估条件(conditions),即仅当必要时才进行元组的实例化。这一改进极大的减少了前向推理引擎的时空复杂度,极大提高了规则执行速度。
Leaps算法将所有的 asserted 的 facts ,按照其被 asserted 在 Working Memory 中的顺序( FIFO ),放在主堆栈中。它一个个的检查 facts ,通过迭代匹配 data type 的 facts 集合来找出每一个相关规则的匹配。当一个匹配的数据被发现时,系统记住此时的迭代位置以备待会的继续迭代,并且激发规则结果( consequence )。当结果( consequence )执行完成以后,系统就会继续处理处于主堆栈顶部的 fact 。如此反复。
Leaps算法的效率可以比Rete算法和Tread算法快几个数量级
3.4规则集中化
通过使用规则,可以创建出一个可运行的知识库。这就意味着对于业务规则可以具备良好的可阅读性,可以起到文档的作用
3.5易懂的规则
通过模型对象以及模型说明语言(Domain Specific Languages)能让你使用很接近自然语言的方式为领域问题建模。借助于这些方式,可让非技术领域的业务使用来描述业务问题
4.Drools规则模板
|
4.1无约束匹配模式
rule "1002"
when
ProductManageVo()
then
System.out.println("无约束的匹配模式,匹配ProductManageVo对象即可");
end
4.2有条件匹配模式
rule "1003"
when
ProductManageVo(topPrice>0)
then
System.out.println("有条件匹配模式,ProductManageVo.topPrice>0即可");
end
4.3匹配并绑定属性模式
rule "1004"
when
event:ProductManageVo($topPrice : topPrice>0)
then
System.out.println("有条件匹配模式,ProductManageVo.topPrice>0;" +"并赋值属性:"+event.getBarcode()+",$topPrice="+$topPrice);
end
5.Drools支持的条件约束
rule "1005"
when
ProductManageVo(thirdPrice!=null&&topPrice>0)
then
System.out.println("条件约束表达式");
end
约束 | 描述 |
!. | 使用此运算符可以以空安全的方式取消引用属性。!.运算符左侧的值不能为null(解释为!= null) |
[] | 按List索引访问值或Map按键访问值 |
<,<=,>,>= | 在具有自然顺序的属性上使用这些运算符 |
==, != | 在约束中使用这些运算符作为equals()和!equals()方法 |
&&,|| | 组合关系条件 |
matches,not matches | 使用这些运算符可以指示字段与指定的Java正则表达式匹配或不匹配 |
contains,not contains | 使用这些运算符可以验证Array或字段是否包含或不包含指定值 |
memberOf,not memberOf | 使用这些运算符可以验证字段是否为定义为变量Array的成员 |
soundslike | 使用英语发音来验证单词是否具有与给定值几乎相同的声音(类似于该matches运算符) |
in,notin | 使用这些运算符可以指定一个以上的可能值来匹配约束(复合值限制) |
6.Drools集合应用
6.1从集合中取数据
rule "1006"
when
$event:ProductManageVo()
$backList : BackList(type==0) from $event.backLists
then
System.out.println("遍历集合数据:"+$backList);
end
7.SpringBoot引入Drools.jar
|
8.Java Demo
RiskConfig表结构
CREATE TABLE `r_risk_config` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`risk_code` varchar(128) NOT NULL COMMENT '规则编码',
`risk_name` varchar(256) DEFAULT NULL COMMENT '规则名称',
`risk_content` text COMMENT '规则模板',
`risk_key` varchar(64) DEFAULT NULL COMMENT '规则模板md5,验证是否需要重新加载',
`risk_type` tinyint(3) DEFAULT '0' COMMENT '0-商品,1-订单',
`risk_level` tinyint(3) DEFAULT '0' COMMENT '风控等级',
`is_send_email` tinyint(3) DEFAULT '0' COMMENT '是否发送邮件0-否,1-是',
`is_wx_news` tinyint(3) DEFAULT '1' COMMENT '是否发送告警信息0-否,1-是',
`is_fuse` tinyint(3) DEFAULT '0' COMMENT '是否熔断流程0-否,1-是',
`is_black_list` tinyint(3) DEFAULT '0' COMMENT '是否添加黑名单0-否,1-是',
`status` tinyint(3) NOT NULL DEFAULT '1' COMMENT '是否生效0-否,1-是',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`creator` bigint(20) DEFAULT NULL COMMENT '创建人',
`modifier` bigint(20) DEFAULT NULL COMMENT '修改人',
`modify_time` datetime DEFAULT NULL COMMENT '修改时间',
`dr` tinyint(1) DEFAULT '0' COMMENT '删除标志',
`ver` int(11) DEFAULT '1' COMMENT '版本号',
`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_risk_code` (`risk_code`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='风控规则表';
规则模板RiskConfig配置
|