Drools规则引擎技术在天梯项目中的应用
今天主要来给大家分享一下Drools规则引擎的原理与规则配置。在介绍之前,首先给大家介绍一下我行研发的SQL评测优化项目——天梯系统,大数据天梯系统是一款智能分析 SQL 评测工具,不仅可以提高脚本上线效率,降低人员工作量,而且可以针对各种查询的算力消耗、数据安全及代码规范,提取代码特征,及时发现代码质量、安全、性能等问题,避免太差的 SQL进入生产系统,为系统的稳定与健康运行提供有效保障。天梯系统设计的初衷是用户可以根据定义的规则,对SQL语句进行评测,以免在生产环境中出问题。天梯系统在开发过程中可以把业务逻辑从硬编码中解耦,达到修改业务逻辑不更改代码、不用重新编码、减少对系统其他功能影响。天梯系统主要由SQL语法解析和SQL评测两部分组成,在SQL评测阶段,用到了Drools规则引擎,它是天梯系统尤为重要的核心部分。Drools规则引擎是否能够挑起大梁呢?事实证明,它做到了!
Drools是一款基于 Java的开源规则引擎,将复杂多变的规则从硬编码中解放出来,以规则脚本形式存放在文件中,使得规则的变更不需要修正代码、重启机器,就可以立即在线上环境生效。规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策,从而给编程带来了极大的方便。
Drools规则引擎有什么优点呢?如上图1所示,可以很直观的看出来,Drools规则引擎可以将业务规则与业务系统分离,解耦合。同时,Drools可实现自然语言描述规则逻辑,业务人员易于理解。并且可以可视化的规则定制、审批、查询及管理。有效的提高实现复杂逻辑的代码的可维护性。在客户一开始没有提到要将业务逻辑考虑在内的情况时,也可以在后续定制规则,对于开发者而言,符合组织对敏捷或迭代开发过程的使用。
Drools有这么多优点,那么它的基本工作过程是如何实现呢?之前我们一般的做法都是使用一个接口进行业务的工作,首先要传进去参数,其次要获取到接口的实现执行完毕后的结果。Drools在这方面与我们以往的做法不谋而合,Drools也需要传递进去数据,用于规则的检查,调用外部接口,同时还可能需要获取到规则执行完毕后得到的结果。在Drools中,这个传递数据进去的对象是一个普通的JavaBean,一个JavaBean插入到Working Memory(内存存储)中后的对象称为Fact对象,Fact对象不是对原来的JavaBean对象进行克隆,而是原来 JavaBean 对象的引用,简单点,可以把Fact对象理解为规则与应用系统数据交互的桥梁或通道。对于Fact对象其中的属性,需要提供getter和setter方法,通过getter和setter方法可以方便的对Fact对象进行相关操作。
之后,Fact对象会与当前WorkingMemory当中所有的规则进行匹配,同时返回一个FactHandler对象。FactHandler对象是插入到 WorkingMemory 当中 Fact 对象的引用,通过 FactHandler 对象可以实现对对应的Fact对象通过API进行删除及修改等操作。
接下来介绍Drools规则引擎规则文件的配置情况,Drools规则引擎配置文件支持多种格式,最基本的是*.drl文件,当然也可以是*.xml的方式,还可以是*.xls或者*.xlsx的方式。看着就很灵活,是吧!在天梯项目中使用的是*.drl文件的格式。
Drools的基础语法可分为三块内容,包路径、引用、规则体;一个最简单的规则至少要包含包路径,规则体这两部分。一个规则文件可以存放多个规则,除此之外,在规则文件当中还可以存放用户自定义的函数、数据对象及自定义查询等相关的在规则当中可能会用到的一些对象。简单的规则文件结构见下图,
在一个规则体当中when与then中间的部分就是条件部分。这部分可以包含0-n个条件,如果条件部分为空的话,那么引擎会自动添加一个 eval(true)的条件,即条件部分返回true。
结果部分是then和end之间的内容,只有在条件部分所有条件都满足时该部分才会执行,类似于Java程序中的条件语句。在结果部分里面,提供了一些对当前Working Memory实现快速操作的宏函数或对象,比如insert、update、modify 和retract就可以实现对当前WorkingMemory 中的 Fact 对象进行新增、修改或者是删除。
Drools规则引擎基本工作过程和规则文件配置基本就是这些内容。接下来自己也动手简单的实现了Drools的API调用程序,首先创建了一个maven项目,相关文件目录及代码见下图。
在这里着重介绍一下kmodule.xml.
- 一个kmodule里面可包含多个kbase,每一个kbase都有一个name,可以取任意字符串,但是不能重名。然后有一个packages,可以看到packages里面的字符串其实就是src/main/resources下面的文件夹的名称,或者叫包名,规则引擎会根据这里定义的包来查找规则定义文件。可以同时定义多个包,以逗号分隔开来就行。每一个kbase下面可以包含多个ksession,在本例中只定义了一个。
- 每一个ksession有一个name,名字也可以是任意字符串,但是也不能重复。kbase和ksession里面的name属性是全局不能重复的。kbase和ksession中其实还有很多其它的属性,每一个kbase下面可以包含多个ksession。
- 运行时,KieContainer会根据kmodule.xml文件来创建相应的KieModule、KieBase、KieSession对象。其中KieModule和KieBase只会创建一次,而KieSession则有可能创建多次,因为KieSession的创建成本很低,同时KieSession包含了运行时的数据,所以可以销毁、创建若干次。
项目程序最终执行结果(成功执行):
Drools规则引擎之旅到此告一段落,相信通过以上的分享,我们已经对Drools规则引擎有了初步的了解,并且相关项目代码执行调试成功,下一步要具体的在天梯项目中进行实战,达到可以根据相应的需求配置相应规则的目的,解决规则引擎配置过程中出现相关的一些问题。
作者:dreamsong