news 2026/9/6 15:01:13

规则引擎Drools实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
规则引擎Drools实战

概述

规则引擎起源于基于规则的专家系统,而基于规则的专家系统又是专家系统的其中一个分支。专家系统属于人工智能的范畴,它模仿人类的推理方式,使用试探性的方法进行推理,并使用人类能理解的术语解释和证明它的推理结论。
利用它就可以在应用系统中分离商业决策者的商业决策逻辑和应用开发者的技术决策,并把这些商业决策放在中心数据库或其他统一的地方,让它们能在运行时可以动态地管理和修改,从而为企业保持灵活性和竞争力提供有效的技术支持。
在需求里面往往把约束,完整性,校验,分支流等都可以算到业务规则里面。在规则引擎里面谈的业务规则重点是谈当满足什么样的条件的时候,需要执行什么样的操作。因此一个完整的业务规则包括条件和触发操作两部分内容。而引擎是事物内部的重要的运行机制,规则引擎即重点是解决规则如何描述,如何执行,如何监控等一系列问题。
规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。

优点

  • 声明式编程:规则可以很容易地解决困难的问题,并得到解决方案的验证。与代码不同,规则以较不复杂的语言编写,业务分析师可以轻松阅读和验证一套规则;
  • 逻辑和数据分离:数据位于域对象中,业务逻辑位于规则中;
  • 速度和可扩展性:写入Drools的Rete OO算法已经是一个成熟的算法。如果频繁更改请求,可以添加新规则,而无需修改现有规则
  • 知识集中化:通过使用规则,您创建一个可执行的知识库(知识库)。理想情况下,规则是可读的,它们也可以用作文档

Rete算法

最初是由卡内基梅隆大学的Charles L.Forgy博士在1974年发表的论文中所阐述的算法,该算法提供专家系统的一个高效实现。自Rete算法提出以后,它就被用到一些大型的规则系统中,像ILog、Jess、JBoss Rules等都是基于RETE算法的规则引擎。

Rete,在拉丁语中译为net,即网络。Rete匹配算法是一种进行大量模式集合和大量对象集合间比较的高效方法,通过网络筛选的方法找出所有匹配各个模式的对象和规则。

其核心思想是将分离的匹配项根据内容动态构造匹配树,以达到显著降低计算量的效果。Rete算法可以被分为两个部分:规则编译和规则执行。当Rete算法进行事实的断言时,包含三个阶段:匹配、选择和执行,称做match-select-act cycle。

rate算法参考:开源规则流引擎实践

Java开源的规则引擎有:Drools、Easy Rules、Mandarax、IBM ILOG。

Drools

官网,易于访问企业策略、易于调整及易于管理的开源(GitHub,6.3K Star,2.6K Fork)业务规则引擎,符合业内标准,速度快、效率高。用Java语言编写,使用Rete算法对所编写的规则求值。允许使用声明方式表达业务逻辑。可使用非XML的本地语言编写规则,从而便于学习和理解。还可将Java代码直接嵌入到规则文件中,业务分析师人员或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行所需的业务规则。

优势:
易用、执行速度快、兼容Java Rule Engine API,即JSR 94。

概念:
事实:Fact,对象之间及对象属性之间的关系
规则:Rule,是由条件和结论构成的推理语句,一般表示为if…Then。一个规则的if部分称为LHS,then部分称为RHS。
模式:Module,指IF语句的条件。IF条件可能是有几个更小的条件组成的大条件。模式就是指的不能在继续分割下去的最小的原子条件。

依赖:

<dependency><groupId>org.drools</groupId><artifactId>drools-core</artifactId></dependency>

Drools通过事实、规则和模式相互组合来完成工作。有专门的规则语法drl,就是专门描述活动的规则是如何执行的。

DSL

Domain Specific Language

.drl、.dslr或.xls文件

规则语言

一个规则通常包括三个部分:属性部分( attribute)、 条件
部分( LHS)和结果部分( RHS)

规则流

宏对象

实战

用户支付金额和对应送多少积分的规则如下:

100元(含)以下,不加分 100元-500元(含),加100分 500元(不含)以上,加500分

写出的规则文件point-rulesKS.drl

package rulesimportcom.johnny.drools.entity.Order rule"zero"no-looptruelock-on-activetruesalience1when$s:Order(amout<=100)then$s.setScore(0);update($s);end rule"add100"no-looptruelock-on-activetruesalience1when$s:Order(amout>100&&amout<=500)then$s.setScore(100);update($s);end rule"add500"no-looptruelock-on-activetruesalience1when$s:Order(amout>500)then$s.setScore(500);update($s);end

说明:

  • package:与Java语言类似,drl的头部需要有package和import的声明,package不必和物理路径一致
  • import:导出Java Bean的完整路径,也可以将Java静态方法导入调用
  • rule:规则名称,需保持唯一性,可以无限次执行
  • no-loop:定义当前的规则是否不允许多次循环执行,默认是false,也就是当前的规则只要满足条件,可以无限次执行
  • lock-on-active:设置为true,可避免因某些Fact对象被修改而使已经执行过的规则再次被激活执行
  • salience:用来设置规则执行的优先级,值是一个数字,可以是负数,数字越大执行优先级越高。默认为0。如果不设置规则的salience 属性,那么执行顺序是随机的
  • when:条件语句,当到达什么条件时
  • then:根据条件的结果,来执行什么动作
  • end:规则结束

放置在resources/META-INF/kmodule.xml目录下的配置文件告诉代码规则文件drl在哪里:

<kmodule><kbasename="point-rulesKB"packages="rules"><ksessionname="point-rulesKS"/></kbase></kmodule>

解释:

  • Kmodule:可以包含一个到多个 kbase,分别对应 drl 的规则文件
  • Kbase:需要一个唯一的name,可以取任意字符串
  • packages为drl文件所在resource目录下的路径。注意区分drl文件中的package与此处的package不一定相同。多个包用逗号分隔。默认情况下会扫描 resources目录下所有(包含子目录)规则文件
  • kbase的default属性,标示当前KieBase是不是默认的,如果是默认的则不用名称就可以查找到该 KieBase,但每个 module 最多只能有一个默认 KieBase
  • kbase:可以有一个或多个ksession,ksession 的name属性必须设置,且必须唯一
publicstaticvoidmain(String[]args)throwsException{KieServicesks=KieServices.Factory.get();KieContainerkc=ks.getKieClasspathContainer();execute(kc);}privatestaticvoidexecute(KieContainerkc)throwsException{KieSessionksession=kc.newKieSession("point-rulesKS");ksession.insert(null);ksession.fireAllRules();ksession.dispose();}

首先请求获取KieServices,通过KieServices获取KieContainer,KieContainer加载规则文件并获取KieSession,KieSession来执行规则引擎,KieSession是一个轻量级组件,每次执行完销毁。KieContainer是重量级组建,需考虑复用。

概念

Fact对象

API

规则编译、规则收集和规则执行

KnowledgeBuilder

KnowledgeBase

StatefulKnowledgeSession

StatelessKnowledgeSession

KnowledgeBaseConfiguration

规则属性

不完全列表

属性名称默认值解释
activation-group激活分组
agenda-group议程分组
auto-focusfalse
date-effective生效时间
date-expires失效时间
dialectJava或Mvel
duration定时器
enabledtrue设置为false,则规则体将不被激活
lock-on-activefalse设置为true,当前只会被触发一次。解决死循环
no-loopfalse设置为true,避免当前规则then部分被修改后的事实对象再次被激活,从而防止死循环的发生,即执行下面的规则
ruleflow-group规则、流程、分组,即规则流
salience0规则体被执行的顺序。不设置salience属性,规则体的执行顺序为由上到下。salience可以是负数,值越大,执行顺序越高
timer

关键词

有硬关键词和软关键词之分。

硬关键字主要包括true、false、null,规则文件不能使用。

软关键词,在规则文件里可以使用,但是得以驼峰命名格式作为字段名的部分,如someRule。包括:lock-on-active、date-effective、date-expires、no-loop、auto-focus、activation-group、agenda-group、ruleflow-group、entry-point、duration、package、import、dialec、salience、enabled、attributes、rule、extend、template、query、declare、function、global、eval、not、in、or、and、exists、forall、action、reverse、result、end、init等。

参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 15:00:40

MySQL安装步骤

1.、下载地址 https://dev.mysql.com/downloads/mysql/ ,点击 Windows (x86, 64-bit), ZIP Archive 后的 Download&#xff08;下载&#xff09;按钮。 在打开的页面点击“ No thanks, just start my download. ”&#xff08;不用了&#xff0c;谢谢&#xff0c;开始下载吧。…

作者头像 李华
网站建设 2026/9/6 14:58:46

基于STM32的自制OBD数据采集系统:从CAN总线到ECU解析的完整实现

简介&#xff1a;基于STM32单片机的汽车OBD数据采集系统设计方案文档&#xff0c;面向嵌入式开发、汽车电子及车联网相关技术人员。文档详细阐述了系统组成结构与技术实现&#xff0c;针对传统OBD智能盒子数据处理弱、抗干扰差、缺乏互联等痛点&#xff0c;给出完整解决思路。资…

作者头像 李华
网站建设 2026/9/6 14:52:03

嘉格纳嵌入式微波炉安装避坑指南:尺寸散热与电气细节

简介&#xff1a;嘉格纳BMP224/225微波炉安装说明书为官方PDF文档&#xff0c;适合家电安装师傅、售后维修人员以及自行选购嵌入橱柜的用户参考&#xff0c;用于确保该型号微波炉在安装过程符合安全规范与电气法规。资源共1个PDF文件&#xff0c;体积约1.06MB&#xff0c;内含多…

作者头像 李华
网站建设 2026/9/6 14:50:00

git commit message 格式规范

在工作中&#xff0c;我们肯定会与git打交道。那么当你提交代码后如何让别人很快了解到你此次提交代码的改动点是哪些。此时就需要一个提交信息来描述此次提交修改的内容。没有格式的提交信息&#xff0c;会使提交记录杂乱无章&#xff0c;不能很快的定位哪些提交涉及代码修改&…

作者头像 李华
网站建设 2026/9/6 14:49:07

基于改进A*算法的机器人路径规划优化实践

简介&#xff1a;针对移动机器人全局路径规划中的局部最优、转折点多和动态避障不足等问题&#xff0c;这份PDF研究论文提出了基于改进A星算法的解决方案&#xff0c;主要面向机器人、机器学习及相关领域的工程师与研究者。资源为单篇论文&#xff0c;共1个文件&#xff0c;大小…

作者头像 李华
网站建设 2026/9/6 14:49:02

STM32 SPI通信调试:从CS建立时间到时钟模式的完整排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华