Drools规则引擎

规则引擎的概念

现实生活中,规则无处不在。我们的日常生活是由规则驱动的。每次我们在开车的时候停在红灯处,之所以这样做,因为我们遵循一条规则,灯变红时我们应该停下来。如果你跳起来,最终会落到地面,这是由地球引力所决定的。

对于某些企业级应用,诸如欺诈检测软件,购物车,活动监视器,信用和保密应用之类的系统,经常会有大量的、错综复杂的业务规则配置,而且随着企业管理者的决策变化,这些业务规则也会随之发生更改。 我们开发人员不得不一直处理软件中的各种复杂问题,不仅需要将所有数据进行关联,还要尽可能快地一次性处理更多的数据,甚至还需要以快速的方式更新相关机制。

规则引擎,全称为业务规则管理系统,英文名为BRMS(即Business Rule Management System)。规则引擎的主要思想是将应用程序中的业务决策部分分离出来,并使用预定义的语义模块编写业务决策(业务规则),由用户或开发者在需要时进行配置、管理。

为什么要使用规则引擎

如果只是一个或几个逻辑判断,确实没有必要使用规则引擎,命令行语言可以更好地满足我们的需求。然而,业务规则往往是一个庞大且不断变化的规则组合,这使得系统非常复杂,如果只是使用常规代码,则会产生大量的维护工作。

几乎所有复杂的业务场景都是由大量简单规则组成,它们共同提供了全面的复杂评估。整个评估过程开始于某一个简单的规则,然后不断地进行推导及冲突处理,最终得到一个评估结果。

规则引擎起源于基于规则的专家系统,利用它可以在应用系统中分离商业决策者的商业决策逻辑和应用开发者的技术决策,并把这些商业决策放在中心数据库或其他统一的地方,让它们能在运行时可以动态地管理和修改,从而为企业保持灵活性和竞争力提供有效的技术支持。

规则引擎的优势

1、业务规则与系统代码分离,实现业务规则的集中管理

2、在不重启服务的情况下可随时对业务规则进行扩展和维护

3、可以动态修改业务规则,从而快速响应需求变更

4、规则引擎是相对独立的,只关心业务规则,使得业务分析人员也可以参与编辑、维护系统的业务规则

5、减少了硬编码业务规则的成本和风险

6、使用规则引擎提供的规则编辑工具,使复杂的业务规则实现变得的简单

规则引擎的应用场景

对于一些存在比较复杂的业务规则并且业务规则会频繁变动的系统比较适合使用规则引擎,如下:

1、风险控制系统----风险贷款、风险评估

2、反欺诈项目----银行贷款、征信验证

3、决策平台系统----财务计算

4、促销平台系统----满减、打折、加价购

常见的规则引擎

规则引擎实现了将业务决策从应用程序代码中分离出来,接收数据输入,解释业务规则,并根据业务规则做出业务决策。规则引擎其实就是一个输入输出平台。

规则引擎并不是一个具体的技术框架,而是指的一类系统,即业务规则管理系统。

目前市面上具体的规则引擎产品有:drools、VisualRules、Easy Rules、Mandarax、IBM iLog ,其中使用最为广泛并且开源的是drools 。

drools规则引擎的介绍

drools是一款由JBoss组织提供的基于Java语言开发的开源规则引擎,可以将复杂且多变的业务规则从硬编码中解放出来,以规则脚本的形式存放在文件或特定的存储介质中(例如存放在数据库中),使得业务规则的变更不需要修改项目代码、重启服务器就可以在线上环境立即生效。

drools官网地址:https://drools.org/

drools源码下载地址:https://github.com/kiegroup/drools

drools 语法 – 规则文件

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

package:对一个规则文件而言,package是必须定义的,必须放在规则文件第一行,package的名字是随意的,不必必须对应物理路径,跟java的package的概念不同,这里只是逻辑上的一种区分,如:

package com.sankuai.meituan.waimai.drools.demo

import:导入规则文件需要使用到的外部规则文件或者变量,这里的使用方法跟java相同,但是不同于java的是,这里的import导入的不仅仅可以是一个类,也可以是这个类中的某一个可访问的静态方法,如:

import com.drools.demo.point.PointDomain;

global:global用于定义全局变量。用于使应用对象对一系列规则有效。通常,用于向规则提供全局的数据和服务,特别是一些用于规则序列的应用服务,如日志、规则序列中累加的值等。全局的变量是不会插入Woking Memory中的,另外,全局变量不要用于建立规则的条件部分,除非它是一个不会改变的常量。全部变量的改变不会通知到规则引擎,规则引擎不跟踪全局变量的变化,因为他们并没有加入到Woking Memory中。

function:function提供了一种在规则源文件中插入语义代码的方式,使用函数的最主要优点就是你可以把所有逻辑放在一个地方,你可以根据需要更改这些函数的逻辑。函数通常用于在规则的then部分调用某些动作,特别是一些经常被用到的而传入参数不一样的动作。

query:查询是在工作内存中搜索符合所述条件的事实的简单方法,以 query 关键字开始,以 end 关键字结束,在 package 当中一个查询要有唯一的名称,查询的内容就是查询的条件部分,条件部分内容的写法与规则的 LHS 部分写法完全相同。

QueryResults results = ksession.getQueryResults( "people over the age of 30" );

for ( QueryResultsRow row : results ) {

Person person = ( Person ) row.get( “person” );

System.out.println( person.getName() + "\n" );

}

rule:定义一个具体规则。rule "ruleName"。一个规则可以包含三个部分:

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

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

结果部分(RHS): 即当前规则条件满足后执行的操作,可以直接调用Fact对象的方法来操作应用。这里可以写普通java代码

drools 语法 –属性详情

no-loop: 定义当前的规则是否不允许多次循环执行,默认是false

lock-on-active:lock-on-active true 通过这个标签,可以控制当前的规则只会被执行一次,因为一个规则的重复执行不一定是本身触发的,也可能是其他规则触发的,所以这个是no-loop的加强版

date-expires:设置规则的过期时间,默认的时间格式:“日-月-年”

date-effective:设置规则的生效时间,时间格式同上

duration:规则定时,duration 3000,3秒后执行规则

salience:优先级,数值越大越先执行,这个可以控制规则的执行顺序

条件部分-LHS

when:规则条件开始。条件可以单个,也可以多个,多个条件一次排列如:当前规则只有在这三个条件都匹配的时候才会执行RHS部分

eval(true):是一个默认的api,true 无条件执行,类似于 while(true)

操作符:>、>=、<、<=、==、!=、contains、not contains、memberOf、not memberOf、matches、not matches

contains: 对比是否包含操作,操作的被包含目标可以是一个复杂对象也可以是一个简单的值

not contains:与contains相反

memberOf:判断某个Fact属性值是否在某个集合中,与contains不同的是他被比较的对象是一个集合,而contains被比较的对象是单个值或者对象

not memberOf:与memberOf正好相反

matches:正则表达式匹配

结果部分- RHS

当规则条件满足,则进入规则结果部分执行,结果部分可以是纯java代码

insert:往当前workingMemory中插入一个新的Fact对象,会触发规则的再次执行,除非使用no-loop限定

update:更新

modify:修改,与update语法不同,结果都是更新操作

retract:删除

注释(Comments)

drl文件中的注释采用类Java语法的方式,可以分为两类:单行注释和多行注释。

单行注释可以简单的使用双斜杠"//"来标识。多行注释主要用于在代码块外对整个文件进行注释,以"/"开头和"/"结尾的之间所有的内容都会被语法解析器解释为注释。

rule "Testing Comments"

when

// this is a single line comment

eval( true ) // this is a comment in the same line of a pattern

then

/* this is a comment inside

a semantic code block */

end

Drools 原理

Drools 规则引擎基于 ReteOO 算法(对面向对象系统的Rete算法进行了增强和优化的实现),它将事实(Fact)与规则进行匹配,以推断相应的规则结果,这个过程称之为模式匹配。

规则引擎默认不会在规则评估时立即执行业务规则,除非我们强制指定。当我们到达一个事实(Fact)与规则相匹配的节点时,规则评估会将规则操作与触发数据添加到一个叫作议程(Agenda)的组件中,如果同一个事实(Fact)与多个规则相匹配,就认为这些规则是冲突的,议程(Agenda)使用冲突解决策略(Conflict Resolution strategy)管理这些冲突规则的执行顺序。

整个生命周期中,规则评估与规则执行之间有着明确的分割。规则操作的执行可能会导致事实(Fact)的更新,从而与其它规则相匹配,导致它们的触发,称之为前向链接。

Drools 规则是在 Java 应用程序上运行的,其要执行的步骤顺序由代码确定。为了实现这一点,Drools 规则引擎将业务规则转换成执行树,如下图所示:

如上图所示,每个规则条件分为小块,在树结构中连接和重用。每次将数据添加到规则引擎中时,它将在与此类似的树中进行求值,并到达一个动作节点,在该节点处,它们将被标记为准备执行特定规则的数据。

相关概念

drools规则引擎由以下三部分构成:

Working Memory(工作内存)

Rule Base(规则库)

Inference Engine(推理引擎)

其中Inference Engine(推理引擎)又包括:

Pattern Matcher(匹配器)

Agenda(议程)

Execution Engine(执行引擎)

Working Memory:工作内存,drools规则引擎会从Working Memory中获取数据并和规则文件中定义的规则进行模式匹配,所以我们开发的应用程序只需要将我们的数据插入到Working Memory中即可,例如本案例中我们调用kieSession.insert(order)就是将order对象插入到了工作内存中。

Fact:事实,是指在drools 规则应用当中,将一个普通的JavaBean插入到Working Memory后的对象就是Fact对象,例如本案例中的Order对象就属于Fact对象。Fact对象是我们的应用和规则引擎进行数据交互的桥梁或通道。

Rule Base:规则库,我们在规则文件中定义的规则都会被加载到规则库中。

Pattern Matcher:匹配器,将Rule Base中的所有规则与Working Memory中的Fact对象进行模式匹配,匹配成功的规则将被激活并放入Agenda中。

Agenda:议程,用于存放通过匹配器进行模式匹配后被激活的规则。

Execution Engine:执行引擎,执行Agenda中被激活的规则。

Drools Jar 包介绍

knowledge-api.jar - 提供接口和工厂。它清楚地描述用户 API 的职责,还有什么引擎 API。

knowledge-internal-api.jar - 提供内部接口和工厂。

drools-core.jar - 核心引擎,运行时组件。包含 RETE 引擎和 LEAPS 引擎。

drools-compiler.jar - 包含编译器/构建器组件,以获取规则源,并构建可执行规则库。

drools-decisiontables.jar - 决策表编译器组件,在 drools-compiler 组件中使用。支持 Excel 和 CSV 输入格式。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code.song

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值