【Java】 JAVA常见规则引擎对比

JAVA常见规则引擎对比

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

规则条件匹配的效率决定了引擎的性能,引擎需要迅速测试工作区中的数据对象,从加载的规则集中发现符合条件的规则,生成规则执行实例。

Java规则引擎规范: Java Rule Engine API JSR-94

规则概念介绍

定义规则

大多数业务规则可以由以下定义表示:

  • 名称:规则命名空间中的唯一规则名称
  • 说明:规则的简要说明
  • 优先级:相对于其他规则的规则优先级
  • 事实:去匹配规则时的一组已知事实
  • 条件:为了匹配该规则,在给定某些事实的情况下应满足的一组条件
  • 动作:当条件满足时要执行的一组动作(可以添加/删除/修改事实)

    引擎术语

  • Fact,事实对象,对于真实事物或者事实的承载对象,POJO对象。
  • Rule,规则,由条件构成和结论构成的推理语句。例如:if … then … else …..。多个规则组成规则集。
  • LHS,规则的左半部分,通常指规则的if…. 部分。
  • RHS,规则的右半部分,通常指规则的then以及else部分。一般是指具体的action具体的动作。
  • 知识包,知识包是打包了,某一个业务场景下,所有的规则,所有的库文件(Fact元数据描述库,动作库,常量库,枚举库),甚至包括评分卡,决策流等。一个知识包往往是一个业务场景下大的集- 合,知识包都有版本概念,可以发布新版本的知识包,当有新的知识包发布,所有依赖某个业务规则的客户端,都会更新为最新知识包下的规则。
  • workmemory,工作区,即执行规则的内存空间,一个workmemory对应一次回话,对应一次规则的执行。
  • Rete,由LHS部分构成的规则网络,通常是dag图。
  • Agenda,议程,决定执行哪些RHS的Action。
  • Action,动作,RHS部分对应的具体动作,例如:赋值,打印参数,执行方法等。

    RETE算法

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

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

其核心思想是将分离的匹配项根据内容动态构造匹配树(其实是构造一个DAG,有向无环图),以达到显著降低计算量的效果。Rete 算法可以被分为两个部分:规则编译和规则执行 。当 Rete 算法进行事实的断言时,包含三个阶段:匹配、选择和执行,称做 match-select-act cycle。本质上是利用空间换换时间,会消耗较多内存。

参考:RETE网络算法

规则引擎的优势

  • 业务规则与系统代码分离,实现业务规则的集中管理
  • 在不重启服务的情况下可随时对业务规则进行扩展和维护
  • 可以动态修改业务规则,从而快速响应需求变更
  • 规则引擎是相对独立的,只关心业务规则,使得业务分析人员也可以参与编辑、维护系统的业务规则
  • 减少了硬编码业务规则的成本和风险
  • 使用规则引擎提供的规则编辑工具,使复杂的业务规则实现变得的简单

    规则引擎应用场景

  • 决策表
  • 质量/风险评估
  • 促销平台

规则引擎选择

规则引擎 官网 开源、收费 社区活跃程度 优点 缺点 性能体现
Drools https://www.drools.org 开源(Apache License 2.0) 很活跃 业务规则管理系统(BRMS)解决方案,应对复杂业务场景 DRL规则语言,学习成本高
Easy Rules https://github.com/j-easy/easy-rules 开源(MIT) 自2020只修复BUG 轻量级、支持表达语言(如MVEL和SpEL) 社区目前维护阶段,无新特性
Oracle Hyperon https://www.hyperon.io/ 商用 - 红帽出品
Aviator(Groovy) http://fnil.net/aviator/ 免费(GPL 3.0) 活跃 高性能、轻量级的java语言实现的表达式求值引擎,主要用于各种表达式的动态求值 AviatorScript语法,学习成本
Rulebook http://deliveredtechnologies.com/ 免费(Apache License 2.0) 不活跃 简单直观的DSL 社区不活跃,长期未维护 未知
OpenL Tablets https://openl-tablets.org/ 免费(LGPL) 活跃 支持Excel 相关文档少
Ilog JRules https://www.ibm.com/products/ilog-cplex-optimization-studio 商用 - IBM
Jess http://herzberg.ca.sandia.gov/jess/ Clips的java实现 上手难度大 极高

根据实际需求选择相应的处理方式

DRL文件

DRL文件结构组成:

1
2
3
4
5
6
package package-name
imports
globals
functions
queries
rules

规则(Rule)组成:

1
2
3
4
5
6
7
rule "name"
attributes
when
LHS
then
RHS
end

Spring中使用

  • KieServices:kie整体的入口,可以用来创建Container,resource,fileSystem等
  • KieContainer: KieContainer就是一个KieBase的容器,可以根据kmodule.xml 里描述的KieBase信息来获取具体的KieSession
  • KieBase: KieBase就是一个知识仓库(knowledge),包含了若干的规则(rule) 、流程(rule flow)、方法(function)等,在Drools中主要就是规则和方法,KieBase本身并不包含运行时的数据之类的,如果需要执行规则KieBase中的规则的话,就需要根据KieBase创建KieSession
  • KieSession:KieSession就是一个跟Drools引擎打交道的会话,其基于KieBase创建,它会包含运行时数据,包含“事实 Fact”,并对运行时数据事实进行规则运算
    • StatefulKnowledgeSession
      • 监控
    • StatelessKnowledgeSession
      • 验证:例如验证某人是否有资格获得抵押贷款
      • 计算:例如计算抵押贷款溢价
      • 路由和过滤:例如将传入的电子邮件分类到文件夹中或将传入电子邮件发送到目标
  • KieModule:是一个包含了多个kiebase定义的容器。一般用META-INF/kmodule.xml来表示

使用流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
┌─────────────────┐
│ │
│ KieServices │
│ │
└────────┬────────┘


┌────────▼────────┐
│ │
│ KieContainer │
│ │
└────────┬────────┘


┌────────▼────────┐
│ │
│ KieSession │
│ │
└────────┬────────┘


┌────────▼────────┐
│ │
│ Insert Fact │
│ │
└────────┬────────┘


┌────────▼────────┐
│ │
│ Fire Rule │
│ │
└────────┬────────┘


┌────────▼─────────┐
│ │
│ Close KieSession │
│ │
└──────────────────┘

DroolsAutoConfiguration.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@Configuration
public class DroolsAutoConfiguration {
private static final String RULES_PATH = "drl/";
@Bean
@ConditionalOnMissingBean(KieFileSystem.class)
public KieFileSystem kieFileSystem() throws IOException {
KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
for (Resource file : getRuleFiles()) {
kieFileSystem.write(ResourceFactory.newFileResource(file.getFile()));
}
return kieFileSystem;
}

@Bean
@ConditionalOnMissingBean(KieContainer.class)
public KieContainer kieContainer() throws IOException {
final KieRepository kieRepository = getKieServices().getRepository();

kieRepository.addKieModule(new KieModule() {
@Override
public ReleaseId getReleaseId() {
return kieRepository.getDefaultReleaseId();
}
});

KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem());
kieBuilder.buildAll();

return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
}

@Bean
@ConditionalOnMissingBean(KieBase.class)
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}

@Bean
@ConditionalOnMissingBean(KieSession.class)
public KieSession kieSession() throws IOException {
return kieContainer().newKieSession();
}

private Resource[] getRuleFiles() throws IOException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
return resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "**/*.*");
}

private KieServices getKieServices() {
return KieServices.Factory.get();
}
}

规则过滤

AgendaFilter

1
2
3
4
5
6
KieServices kieServices = KieServices.get();
KieContainer kc = kieServices.getKieClasspathContainer();
KieSession kieSession = kc.newKieSession("BookOrderKS");

// 根据选择触发
kieSession.fireAllRules(AgendaFilter fileter);
  • RuleNameStartsWithAgendaFilter 执行名称以xxx开头的规则
  • RuleNameEndsWithAgendaFilter 执行名称以xxx结尾的规则
  • RuleNameEqualsAgendaFilter 执行名称全匹配的规则
  • RuleNameMatchesAgendaFilter 可以写自己的正则
  • RuleNameSerializationAgendaFilter 规则名称序列化代理筛选器(其实好像就是可以执行以上4钟中的一钟)

drools处理数据有两种方式,云模式和流模式,默认是云模式,用fusion,需要设置为流模式。流模式,插入的数据叫事件,有时间顺序,云模式没有

后续可使用Drools Fusion进行流(stream)处理

基准测试benchmark

官网测试用例

参考

Drools-7.73.0.Final官方文档

规则引擎核心知识与开源产品对比选型

drools性能优化

Drools集成SpringBoot

KIE简介

记一次drools5的性能优化过程

理解KieSession会话

SparkSQL整合Drools,并用MySQL数据库实现动态规则

复杂事件Drools Fusion怎么用

美团酒旅实时数据规则引擎应用实践

基于 Apache Flink 和规则引擎的实时风控解决方案

Storm VS Flink ——性能对比