规则引擎是什么
规则引擎是一种嵌入在应用程序中的组件,它可以将业务规则从业务代码中剥离出来,使用预先定义好的语义规范来实现这些剥离出来的业务规则;规则引擎通过接受输入的数据,进行业务规则的评估,并做出业务决策。
- 优点
- 基于浏览器的图形化界面
开源版与商用版功能区别
特性 | URULE PRO版 | URULE开源版 |
---|---|---|
向导式决策集 | 支持 | 支持 |
脚本式决策集 | 支持 | 支持 |
决策树 | 支持 | 支持 |
决策流 | 支持 | 支持 |
决策表 | 支持 | 支持 |
交叉决策表 | 支持 | 不支持 |
复杂评分卡 | 支持 | 不支持 |
文件名、项目名重构 | 支持 | 不支持 |
参数名、变量常量名重构 | 支持 | 不支持 |
Excel决策表导入 | 支持 | 不支持 |
规则集模版保存与加载 | 支持 | 不支持 |
中文项目名和文件名支持 | 支持 | 不支持 |
服务器推送知识包到客户端功能的支持 | 支持 | 不支持 |
知识包优化与压缩的支持 | 支持 | 不支持 |
客户端服务器模式下大知识包的推拉支持 | 支持 | 不支持 |
规则集中执行组的支持 | 支持 | 不支持 |
规则流中所有节点向导式条件与动作配置的支持 | 支持 | 不支持 |
循环规则多循环单元支持 | 支持 | 不支持 |
循环规则中无条件执行的支持 | 支持 | 不支持 |
导入项目自动重命名功能 | 支持 | 不支持 |
规则树构建优化 | 支持 | 不支持 |
对象查找索引支持 | 支持 | 不支持 |
规则树中短路计算的支持 | 支持 | 不支持 |
规则条件冗余计算缓存支持 | 支持 | 不支持 |
更为完善的文件读写权限控制 | 支持 | 不支持 |
技术支持 | 支持 | 不支持 |
库文件
映射java中的POJO对象,使得我们可以在具体的规则文件中使用它们,从而完成规则与业务数据的交互。
-
变量库文件
-
常量库文件
-
参数库文件
-
动作库文件
urule的四种模式
-
嵌入式模式
所谓的嵌入式,是指将URule Pro直接嵌入到我们的Java Web应用当中,作为应用的一部分运行。这种模式的好处是配置起来比较简单;而不好的地方在于因为将URule Pro直接嵌入到我们的应用当中,如果我们有多个涉及到规则引擎的应用, 那么每个应用都需要嵌入一个URule Pro模块,所以更多的时候我们使用的是独立服务模式。
-
本地模式
本地模式类似于嵌入式模式,所不同的是嵌入到我们客户端应用中的URule Pro模块仅仅为其规则计算部分(core部分),不含设计器部分(console部分); 之后将测试好的知识包导出为一个.data格式文件,然后把文件放在客户端应用的一个指定目录下或数据库中,这样客户端应用在调用知识包时就直接到这个指定目录下或数据库中查找目标.data文件并加载。开源版的知识包不支持导入和导出,可以使用嵌入式模式,共享数据库的方式来代替。
-
分布式计算模式(服务器客户端模式)
分布式计算模式是指将URule Pro部署为一个独立的Java Web应用,在这个应用里定义各个业务系统所需要业务规则,定义好后统一存储到一个规则存储仓库当中。 业务系统要使用规则时只需要指定URule Pro Server的地址即可通过HTTP协议取到目标规则包,然后解析并运行在分布式计算模式下, 一个URule Pro Server可以下挂多个需要用到规则引擎的业务系统,但实际的业务规则在运行时还是发生在各个业务系统中,而不是URule Pro Server上,所以称之为分布式计算模式。
分布式计算模式下的规则包更新:在分布式计算模式下规则包的更新有两种方式:一种是主动推送方式;一种为定时更新的方式。开源版只支持定时更新,通过urule.knowledgeUpdateCycle来配置。
在客户端启动时,要保证服务端已经启动,并且连接畅通;当使用过程中,服务器停掉后,对客户端无影响,客户端可以继续使用旧的规则。对服务器性能要求不高,基本只有客户端服务启动时才需要访问,计算还是各个应用本身。
-
独立服务模式
独立服务模式也是规则引擎的传统运行模式,那就是把规则的调用以一个Restful服务的形式对外提供,客户端可以是Java、C#、C++或Javascript,客户端只需要把标准的JSON格式的输入数据提交给规则服务器,服务器调用规则计算完成后会以JSON格式作为响应返回。开源版的知识包不支持,可以通过自己实现servlet实现Restful服务的提供。
决策流
-
注意事项
图标无法添加,在浏览器页面右键重新加载框架
如果一个决策集中存在多个规则,决策流只会执行第一个
在编写决策时,开源版只支持脚本,脚本里面的等于要用==,只用=会报匹配错误
在实际的业务系统中往往都是以规则流作为业务规则的调用入口,通过规则流将所有的以点形式存在的规则编排起来执行,从而可以实现任意复杂的业务规则需求。
知识包的测试
URule Pro提供了三种类型,一种为用户选择输入测试值的快速测试,一种为输入复杂JSON的快速测试,另一种为支持基于Excel批量数据的“仿真测试”。开源版只支持浏览器的单条测试,还可以通过API调用的方式。
配置文件
-
context.xml
用于配置和urule相关的bean配置
-
configure.properties
配置urule项目自定义的各种配置,详见:urule安装与配置
urule.repository.dir 当前知识库存放目录 urule.resporityServerUrl 客户端上配置的服务器地址 urule.knowledgeUpdateCycle 用来指定客户端多久到服务端检查当前知识包有没有更新。 urule.welcomePage 一个URL,用于替换URule Pro主界面第一次看到的工作区内容 urule.console.title 一个字符串,用来替代URule控制台页面的title urule.debug 调试信息是否输出
在数据库中存储知识库
- 在context.xml中配置数据库连接信息
<bean id="mysqlDatasource" class="org.apache.commons.dbcp.BasicDataSource"><property name="url"value="jdbc:mysql://127.0.0.1:3306/urule?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false" /><property name="driverClassName" value="com.mysql.jdbc.Driver" /><property name="username" value="root" /><property name="password" value="root" /><property name="minIdle" value="5" /><property name="maxActive" value="10" /><property name="maxWait" value="1000" /><property name="removeAbandonedTimeout" value="60" /><property name="removeAbandoned" value="true" /><property name="logAbandoned" value="true" /></bean>
-
在configure.properties中将目录更换为数据库
# urule.repository.dir=d:/repo2 urule.repository.databasetype=mysql urule.repository.datasourcename=mysqlDatasource
代码调用
-
单次调用
//从Spring中获取KnowledgeService接口实例 KnowledgeService service=(KnowledgeService) Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID); //通过KnowledgeService接口获取指定的资源包"projectName/test123" KnowledgePackage knowledgePackage=service.getKnowledge("dhyh/123"); //通过取到的KnowledgePackage对象创建KnowledgeSession对象 KnowledgeSession session= KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);Customer c = new Customer(); c.setAge(1); //将业务数据对象Employee插入到KnowledgeSession中 session.insert(c); //执行所有满足条件的规则 session.fireRules(); System.out.println(c.getName());GeneralEntity c2 = new GeneralEntity("com.bstek.urule.model.Customer"); c2.put("age", 80); session.insert(c2); session.fireRules(); System.out.println(c2.get("name"));
-
批量执行
//从Spring中获取KnowledgeService接口实例 KnowledgeService service = (KnowledgeService) Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID); //通过KnowledgeService接口获取指定的资源包"aaa" KnowledgePackage knowledgePackage = service.getKnowledge("dhyh/123"); //通过取的KnowledgePackage对象创建BatchSession对象,在这个对象中,我们将开启5个线程,每个线程最多放置10个Bussiness接口实例运行 BatchSession batchSession = KnowledgeSessionFactory.newBatchSession(knowledgePackage, 5, 10); for (int i = 0; i < 100; i++) {Customer c = new Customer();c.setAge(i);batchSession.addBusiness(new Business() {@Overridepublic void execute(KnowledgeSession session) {//将业务数据对象Employee插入到KnowledgeSession中session.insert(c);session.fireRules();System.out.println(c.getAge() + ":" + c.getName());}}); } //等待所有的线程执行完成,对于BatchSession调用来说,此行代码必不可少,否则将导致错误 batchSession.waitForCompletion();
存在的问题
- 对业务人员的要求更高,增加了学习成本。
- 工作量变大,如果只有单个项目使用,工作量会超过代码直接编写业务逻辑,但是好处是规则清晰明了,比看代码中的注释要便捷;当有多个项目使用同一个规则时,此时的边际成本会很低,效率得到最大化。
- 原urule项目中可能会存在问题(商用版本的3.0都存在问题,代码调用知识库一直不更新),虽然开源,但是已经停止版本更新很多年,并且缺失2.0相关的文档,导致修复扩展成本高,简而言之,就是没有技术支持。
- 文件修改不会刷新,需要先删除再重新添加
- 有些操作会导致bug,重启系统后恢复正常
点评
开国内规则引擎之先,从产品设计上来讲,将项目中最复杂的业务逻辑层进行了抽离,一定程度上解决了面条式的耦合代码。
将代码开源,本身就是一种勇气;是对自己公司技术的自信,码农的口口相传,就是对项目最好的推广。
参考
官网