查看原文
其他

瀚云雾计算Drools规则引擎组件使用分享

汪霄 瀚云研发中心 2022-09-08

Drools规则引擎介绍


背景

规则引擎起源于基于规则的专家系统,而基于规则的专家系统又是专家系统的其中一个分支。


专家系统属于人工智能的范畴,它模仿人类的推理方式,使用试探性的方法进行推理,并使用人类能理解的术语解释和证明它的推理结论。 


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


在需求里面我们往往把约束,完整性,校验,分支流等都可以算到业务规则里面。在规则引擎里面谈的业务规则重点是谈当满足什么样的条件的时候,需要执行什么样的操作。


因此一个完整的业务规则包括了条件和触发操作两部分内容。


而引擎是事物内部的重要的运行机制,规则引擎即重点是解决规则如何描述,如何执行,如何监控等一系列问题。 


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


java开源的规则引擎有:Drools、Easy Rules、Mandarax、IBM ILOG。使用最为广泛并且开源的是Drools。


定义

Drools 是一个基于Charles Forgy's的RETE算法的,易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。 


业务分析师人员或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。

 

Drools 是用Java语言编写的开放源码规则引擎,使用Rete算法对所编写的规则求值。Drools允许使用声明方式表达业务逻辑。可以使用非XML的本地语言编写规则,从而便于学习和理解。并且,还可以将Java代码直接嵌入到规则文件中,这令Drools的学习更加吸引人。


为什么需要使用规则?

业务规则往往是一个庞大且不断变化的规则组合,这使得系统非常复杂,如果只是使用常规代码,则会产生大量的维护工作。 


随着业务规则的增长或应用场景的变化,需求会不断地变更,此时,我们可以通过调整规则而使其得到实现。主要是因为业务规则遵循以下原则:

  它们是独立的

  它们很容易更新

  • 每个规则控制所需的最小信息量

   它们允许不同背景的人进行合作

可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效。


规则引擎的优点

•  声明式编程

规则可以很容易地解决困难的问题,并得到解决方案的验证。与代码不同,规则以较不复杂的语言编写; 业务分析师可以轻松阅读和验证一套规则。  

•  逻辑和数据分离

数据位于“域对象”中,业务逻辑位于“规则”中。根据项目的种类,这种分离是非常有利。  

•  速度和可扩展性

写入Drools的Rete OO算法已经是一个成熟的算法。在Drools的帮助下,您的应用程序变得非常可扩展。如果频繁更改请求,可以添加新规则,而无需修改现有规则。

•  知识集中化

通过使用规则,您创建一个可执行的知识库(知识库)。这是商业政策的一个真理点。理想情况下,规则是可读的,它们也可以用作文档。


语法

DRL文件的整体结构如下:

对于上述元素,其顺序在drl文件中的顺序不重要,除了 package-name ,必须是drl文件的第一个元素。上述所有的元素都是可选的,接下来我们将详细介绍上述元素。


包(Package)

package 是一系列 rule 或其他相关构件如 imports, globals 的容器。

这个成员之间相互关联,一个 package 代表了一个命名空间,其中的每个 rule 的名字都是唯一的,package 名字本身就是命名空间,与实际的文件和文件夹没有任何关系。常见的结构是,一个文件包含多个 rule 的文件就定义成一个包。


以下的线路图表明了一个包中包含的所有组成元素

需要注意的是,一个包必须有一个命名空间,且其声明必须遵守Java命名规范。 package 语句必须出现在包的首行,其他组成部分的出现顺序无关紧要。其中 package 语句结尾的分号 ; 是可选的。


引入(import)

Drools文件中的 import 语句功能与Java中的 import 语句功能类似。使用 import 时,必须指定对象的全称限定路径和类型名。Drools会自动导入Java相同名字的包中的所有类,也会导入 java.lang.* 。


 函数(Function)

function 提供了一种在规则源文件中插入语义代码的方式,与在普通Java类中不同。


他们需要帮助类,否则不能做任何事情(实际上,编译器会针对这些句子自动产生帮助类)。


在规则中使用函数的最主要优点就是你可以把所有逻辑放在一个地方,你可以根据需要更改这些函数的逻辑。


函数通常用于在规则的 then 部分调用某些动作,特别是一些经常被用到的而传入参数不一样的动作。 


典型的 function 格式如下:

需要注意的是,这里我们使用了 function 关键字,即使它并不是Java语言的一部分。参数和返回值的定义和传入与Java语言一致。当然,参数和返回值并不是必须的。另外,我们可以使用一个帮助类中的静态方法,如: Foo.hello() 。 


Drools支持函数的导入,我们所要做的就是:

不需要考虑函数的定义和导入方式,我们可以直接在需要的地方直接使用函数名调用这个函数。


例如:


规则(Rule)

一个简单的规则结构如下所示:

一个规则,指定当( when )一系列特定的条件发生时(左手边LHS),然后( then )做出一系列相应的动作(右手边RHS)。


一个常见的问题就是:为什么使用 when 而不是 if ,因为 if 通常是执行流程中特定时间点的一部分,是一个需要检查的条件。


相反地, when 指明的是一个不绑定于任何特定判断序列或时间点的条件判断,它在规则引擎的声明周期内的任何一个条件发生的情况下都可能触发,不管这个条件是否遇到,这些动作都会执行。   


通常,规则文件中是不需要标点符号的。即使是规则名 “name” 上的双引号也是可选的。 attributes 展示规则的执行方式,也是可选的。 LHS 是规则的条件部分,遵循一个固定的语法规则,在下面的内容会详细介绍。 RHS 通常是一个可以本地执行的代码块。   


注意:

a、一个规则在一个包中必须具有独一无二的名字。如果在一个DRL文件中重复定义两个相同名字的规则,在加载的时候就会报错。如果向包中添加一个名字已经存在的规则,该规则会覆盖掉之前的同名规则。如果一个规则命中存在空格符,最好使用双引号将规则名包括起来。   

b、规则的属性不是必须的,且属性最好写成一行。

c、规则中的LHS在关键字 when 的后面,同样的,RHS应该在关键字 then 的后面,规则最后以关键字 end 结尾。另外,规则不准嵌套。



基于Drools规则引擎协议接入实现


整体结构

规约开发套件面向全社会开发人员提供丰富的协议泛在连接组件,通过编写drl脚本实现接入到瀚云平台的设备实现数据接入、数据推送、数据展示等功能。


规约库解析/组装数据格式定义


公用API列表


编写drl文件实现业务操作

业务操作主要分为:数据解析和报文下发,增加定时任务机制,可以周期性采集数据。



固定引入

该部分为固定引入,不做改动,编写code时固定引入,支持引入依赖包白名单列表如下,如果引入不存在白名单中的依赖,code校验无法通过.

1) java.util.* 

2)com.hanclouds.hfc.data.helper.ProtocolApi 

3)com.hanclouds.hfc.common.beans.MessageContext



数据解析

注意:上述报文通过数据长度和首字符数据判断通信报文和数据报文。


定时任务


报文下发


控制指令


附录(以ModBus协议为例)


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存