探析Drools规则引擎的工作机制

目录

一、工作原理

二、工作流程

        2.1 初始化环境

        2.2 添加规则文件

        2.3 编译规则文件

         2.4 插入到工作内存

        2.5 规则匹配与激活

        2.6 规则执行

三、Drools 其他特性

        3.1 符合事实

        3.2 决策表

        3.3 规则生命周期管理

        3.4 规则流

四、Rete 算法


一、工作原理

        Drools 规则引擎的工作原理围绕以下几个核心概念和组件:

        规则(Rules):规则是以声明性的方式表达业务逻辑的关键元素,由条件 LHS 和结论 RHS 构成。条件部分定义了触发规则的情景,结论部分则指明了当条件满足时应执行的动作。

        事实(Fact):事实是传递给规则引擎的数据对象实例,代表了当前的状态或事件。规则引擎会将事实对象放入工作内存(Working Memory)中,规则的条件部分会对这些事实进行匹配。

        工作内存(Working Memory):工作内存是规则引擎暂存事实的地方,也是规则引擎的执行场所。当事实被插入工作内存时,引擎会重新评估所有规则,看是否有规则的条件得到满足。

        生产内存(Production Memory):在 Drools 中,生产内存同村指的是存放规则本身的地方,也就是规则库。这里的规则已经被编译并准备好了执行。

        议程(Agenda):议程负责追踪所有满足条件的规则,以及他们的执行顺序。当规则的条件部分被满足,规则会被添加到议程中等待执行,Drools 支持多种执行策略,如正向链路、反向链路、冲突解决策略等,来决定规则的激活和执行顺序。

        RETE算法 : RETE(Rapidly Exploring Random Trees)或其改进型 RETEOO,是 Drools 规则引擎背后的一种高效模式匹配算法,用于优化规则匹配过程,减少重复计算。它维护一个内部网络结构来跟踪条件之间的关系,以加速对工作内存中变化的事实进行反应。

二、工作流程

        执行流程如下图:

        2.1 初始化环境

        首先,你需要通过 KieServices 获取 KieRepository 和 KieFileSystem,用于管理和加载规则文件。

KieServices kieServices = KieServices.Factory.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();

        2.2 添加规则文件

        将.drl规则文件或者其他类型的资源文件添加到 KieFileSystem 中。

kieFileSystem.write(ResourceFactory.newClassPathResource("rules/myRule.drl"));

        2.3 编译规则文件

        使用 KieBuilder 构建 KieModule,从而将规则文件编译成可执行的形式。

KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll(); // 编译
Results results = kieBuilder.getResults();
if (results.hasMessages(Message.Level.ERROR)) {
    // 处理编译错误
}

KieContainer kieContainer = kieServices.newKieContainer(kieBuilder.getKieModule().getReleaseId());

        通过调用 kieBuilder.buildAll() 方法即可编译规则文件,通过 DrlParser 类来实现 规则文件的编译,并将其存储在规则库中。如下代码调用栈:

        通过上图调用栈课发现,Drools 同时支持多种规则人间类型,经过规则编译后规则就进入到了生产内存中,二所谓的生产内存其实就是 KieBase,它包含了从 .drl 规则文件中加载并编译好的规则。在运行时,可以从这个 KieBase 中创建 KieSession,并在 KieSession 中插入实时对象、执行规则。

        规则编译后的内容如下,详细内容请自行查看。

         2.4 插入到工作内存

        当调用 kieSession.insert(fact); 方法时,对象事实就会插入到工作内存中,所谓的工作内存就是 KieSession。

        2.5 规则匹配与激活

        当某个事实对象被插入或更新时,引擎遍历 Rete 网络,查找与该事实想匹配的规则条件。若规则的所有条件均满足,规则讲呗激活并添加到议程 Agenda 中。

        2.6 规则执行

        通过调用 kieSession.fireAllRules() 方法来触发所有已经匹配的规则开始执行,执行直至 Agenda 为空,即所有符合条件的规则都已经关闭,或者遇到终止条件。

        规则执行的过程可能有副作用,具体包括:更新 Working Memory 中的事实、执行系统外部操作、出发新的规则激活等。

        总之,fireAllRules 方法启动了一轮完成的规则执行周期,该周期会持续地匹配、激活、执行规则,直到没有更多的规则可以执行为止。

        最后需要调用 dispose() 方法用于释放和清理当前 kieSession 相关的所有资源。这样一次完成的规则执行就结束了。

三、Drools 其他特性

        3.1 符合事实

        在复杂的业务场景中,有时需要组合多个对象形成一个新的事实来参与规则匹配。复合事实可以通过事实对象继承、聚合或嵌套等方式构造。

        3.2 决策表

         Drools 支持使用决策表(Spreadsheet Decision Tables)来编写规则,这种方式特别适合于那些基于表格形式展现的复杂条件逻辑,例如Excel文件格式。决策表可以清晰地可视化规则条件和结果,方便非程序员维护。

        3.3 规则生命周期管理

         Drools 支持规则的动态加载、更新和卸载。例如,通过 KieScanner 实现规则库的热部署,当规则文件发生变化时,可以自动重新加载规则。

        3.4 规则流

        使用 Drools Workbench 或 jBPM 流程设计器,可以创建流程图来定义规则执行的顺序和流程,从而实现流程驱动的规则执行。

        在使用规则引擎时有一些需要注意的事项

  1. 注意工作内存管理:不要一次性插入过多的事实对象,否则可能会导致性能下降升值内存溢出。
  2. 规则的组织应保持清晰,毕淼规则交叉和互相依赖。
  3. 对象事实的生命周期要清晰,了解合适插入,何时更新等。
  4. 在并发环境下,注意正确的使用 KieSession 实例。

四、Rete 算法

        Drools Rete 算法是基于Charles Forgy在1979年提出的 Rete 算法的一种实现,它是规则引擎中用于高效处理大量规则和事实的模式匹配算法。Rete 算法的目标是解决在大型规则库中多次检查相同事实的问题,通过构建一种数据结构(Rete网络),将规则条件分割并缓存中间结果,使得当事实发生变化时,只需要沿着网络进行局部传播,大大减少了不必要的计算。

        在 Drools 中,Rete 算法以及其变种(如ReteOO)被用来优化规则引擎的性能,它构建了一个高效的推理网络,该网络能够记住之前的匹配结果,从而在新的事实插入、更新或删除时,迅速识别出受到影响的规则,以及哪些规则条件已经满足,应当被触发执行。

        Rete算法的工作原理如下:

  • 将规则拆分成多个条件节点,并在网络中构建层次结构。
  • 当事实对象插入工作内存时,它们在网络中传播并激活与之匹配的节点。
  • 激活的节点形成路径,如果这条路径上的所有节点都被激活,则规则被视为满足条件,加入到议程(Agenda)中等待执行。

往期经典推荐

深入浅出 Drools 规则引擎-CSDN博客

系统优化都没做过?看这篇就够了-CSDN博客

SpringBoot项目并发处理大揭秘,你知道它到底能应对多少请求洪峰?_一个springboot能支持多少并发-CSDN博客

你真的了解Tomcat一键启停吗?-CSDN博客

直击Redis集群痛点:数据倾斜优化实战,打造高效分布式缓存架构_redis集群实现的集群如何解决数据倾斜-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/511945.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何理解Java注解反射

Java 8 中文版 - 在线API手册 - 码工具 什么是注解 ◆Annotation是从JDK5.0开始引入的新技术 ◆Annotation的作用: 不是程序本身,可以对程序作出解释.(这一点和注释(comment)没什么区别) 可以被其他程序(比如:编译器等)读取 Annotation的格式: > 注解是以&quo…

OSError: Can‘t load tokenizer for ‘bert-base-chinese‘

文章目录 OSError: Cant load tokenizer for bert-base-chinese1.问题描述2.解决办法 OSError: Can’t load tokenizer for ‘bert-base-chinese’ 1.问题描述 使用from_pretrained()函数从预训练的权重中加载模型时报错: OSError: Can’t load tokenizer for ‘…

数据结构栈和堆列

目录 栈: 栈的概念: 栈的实现: 栈接口的实现: 1.初始化栈: 2.入栈: 3.出栈: 4. 获取栈顶元素: 5.获取栈中有效数据的个数: 6.检测栈是否为空,如果为…

搜索二维矩阵 II - LeetCode 热题 21

大家好!我是曾续缘💗 今天是《LeetCode 热题 100》系列 发车第 21 天 矩阵第 4 题 ❤️点赞 👍 收藏 ⭐再看,养成习惯 搜索二维矩阵 II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&…

20240402—Qt如何通过动态属性设置按钮样式?

前言 正文 1、点击UI文件 2、选择Bool型或是QString 3、设置后这里出现动态属性 4、这qss文件中绑定该动态属性 QPushButton[PopBlueBtn"PopBlueBtn"]{background-color:#1050B7;color:#FFFFFF;font-size:20px;font-family:Source Han Sans CN;//思源黑体 CNbor…

Ansys Zemax | 如何将光栅数据从Lumerical导入至OpticStudio(上)

附件下载 联系工作人员获取附件 本文介绍了一种使用Ansys Zemax OpticStudio和Lumerical RCWA在整个光学系统中精确仿真1D/2D光栅的静态工作流程。将首先简要介绍方法。然后解释有关如何建立系统的详细信息。 本篇内容将分为上下两部分,上部将首先简要介绍方法工…

01 Python进阶:正则表达式

re.match函数 使用 Python 中的 re 模块时,可以通过 re.match() 函数来尝试从字符串的开头匹配一个模式。以下是一个简单的详解和举例: import re# 定义一个正则表达式模式 pattern r^[a-z] # 匹配开头的小写字母序列# 要匹配的字符串 text "h…

程序的编译、链接过程分析(简洁浓缩版)!

《嵌入式工程师自我修养/C语言》系列——程序的编译、链接过程分析(简洁浓缩版)! 一、程序的编译1.1 预编译指令 pragma1.2 编译过程概述1.3 符号表和重定位表 二、程序的链接2.1 分段组装2.2 符号决议2.2.1 强符号与弱符号2.2.2 GNU编译器的…

了解与生成火焰图

目录 一、如何看懂火焰图 1、基本特征 2、基本分类 二、如何生成火焰图 1、捕获调用栈 2、折叠栈 3、转换为 svg 格式 4、展示 svg 一、如何看懂火焰图 1、基本特征 (1)纵轴:即每一列代表一个调用栈,每一个格子代表一个函…

智能仓储变革在即,从业者该何去何从?

导语 大家好,我是智能仓储物流技术研习社的社长,你的老朋友,老K。行业群 新书《智能物流系统构成与技术实践》 随着2024年的到来,物流和仓储行业正处于一个技术革命的关键时刻。人工智能(AI)的融入不仅预示…

【二叉树】Leetcode 437. 路径总和 III【中等】

路径总和 III 给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节…

Zabbix6 - Centos7部署Grafana可视化图形监控系统配置手册手册

Zabbix6 - Centos7部署Grafana可视化图形监控系统配置手册手册 概述: Grafana是一个开源的数据可视化和监控平台。其特点: 1)丰富的可视化显示插件,包括热图、折线图、饼图,表格等; 2)支持多数据…

[源码] Android 上的一些快捷方式,如通知、快捷方式等

目录 一、通知0. 配置权限1. 测试发送通知代码2. 打开通知设置界面代码3. 前台服务创建常驻通知 二、快捷方式1. 测试添加动态快捷方式代码 三、开发者图块四、桌面小部件 基于jetpack compose 框架的使用代码 一、通知 参见 官方文档 0. 配置权限 <uses-permission andr…

REST API的指纹验证机制

前端或者客户端涉及数据相关的请求都是不安全的&#xff0c;从某种意义上只能通过一些手段降低请求不被容易使用。本来来介绍一种基于 JWT 的指纹机制。 关于 JWT 令牌机制就不详细介绍了。在 JWT 令牌中包含系统 JWT 指纹可以带来安全改进&#xff0c;而不会给用户带来任何不…

RocketMQ 消费者源码解读:消费过程、负载原理、顺序消费原理

B站学习地址 上一遍学习了三种常见队列的消费原理&#xff0c;本次我们来从源码的角度来证明上篇中的理论。 1、准备 RocketMQ 版本 <!-- RocketMQ --> <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-s…

yolov5关键点检测-实现溺水检测与警报提示(代码+原理)

基于YOLOv5的关键点检测应用于溺水检测与警报提示是一种结合深度学习与计算机视觉技术的安全监控解决方案。该项目通常会利用YOLOv5强大的实时目标检测能力&#xff0c;并通过扩展或修改网络结构以支持人体关键点检测&#xff0c;来识别游泳池或其他水域中人们的行为姿态。 项…

常关型p-GaN栅AlGaN/GaN HEMT作为片上电容器的建模与分析

来源&#xff1a;Modeling and Analysis of Normally-OFF p-GaN Gate AlGaN/GaN HEMT as an ON-Chip Capacitor&#xff08;TED 20年&#xff09; 摘要 提出了一种精确基于物理的解析模型&#xff0c;用于描述p-GaN栅AlGaN/GaN高电子迁移率晶体管&#xff08;HEMT&#xff09…

【Linux】Vim编辑器

专栏文章索引&#xff1a;Linux 目录 在Vim编辑器中&#xff0c;一个Tab键相当于几个空格&#xff1f; 在Vim编辑器中&#xff0c;一个Tab键相当于几个空格&#xff1f; 在Vim编辑器中&#xff0c;默认情况下&#xff0c;一个Tab键相当于8个空格。 这是Vim的默认设置&#x…

【C++】哈希之位图

目录 一、位图概念二、海量数据面试题 一、位图概念 假如有40亿个无重复且没有排序的无符号整数&#xff0c;给一个无符号整数&#xff0c;如何判断这个整数是否在这40亿个数中&#xff1f; 我们用以前的思路有这些&#xff1a; 把这40亿个数遍历一遍&#xff0c;直到找到为…

鸿蒙OS元服务开发:【(Stage模型)设置悬浮窗】

一、设置悬浮窗说明 悬浮窗可以在已有的任务基础上&#xff0c;创建一个始终在前台显示的窗口。即使创建悬浮窗的任务退至后台&#xff0c;悬浮窗仍然可以在前台显示。通常悬浮窗位于所有应用窗口之上&#xff1b;开发者可以创建悬浮窗&#xff0c;并对悬浮窗进行属性设置等操…