规则引擎深度对比,LiteFlow vs Drools!

cd2dcfd57df6b558a9546481a6402a8f.jpeg来源:https://juejin.cn/post/7155672111481094152

👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 /  赠书福利

全栈前后端分离博客项目 2.0 版本完结啦, 演示链接http://116.62.199.48/ ,新项目正在酝酿中。全程手摸手,后端 + 前端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,直到项目上线。目前已更新了239小节,累计38w+字,讲解图:1645张,还在持续爆肝中.. 后续还会上新更多项目,目标是将Java领域典型的项目都整一波,如秒杀系统, 在线商城, IM即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,已有1200+小伙伴加入(早鸟价超低)

a4de57ad5d64da6c18eaa3d5de5b00df.gif

Drools是一款老牌的java规则引擎框架,早在十几年前,我刚工作的时候,曾在一家第三方支付企业工作。在核心的支付路由层面我记得就是用Drools来做的。

难能可贵的是,Drools这个项目在十几年后还依旧保持着开源和更新。

https://github.com/kiegroup/drools

而LiteFlow也是一款java规则引擎,于2020年开源。经过2年的迭代,现在功能和特性也非常棒,很适合用在高复杂度的核心业务上,同时又能保持业务的灵活性。

https://gitee.com/dromara/liteFlow

这篇文章我们就来深入比较下这两款框架,都适合用在什么样的场景,有什么异同点,以及在相同的场景下表现力如何。

(其中Drools基于7.6.0版本,LiteFlow基于2.9.0版本)

虽然题主就是开源项目LiteFlow的作者,但是我这几天也深入了解了下Drools,尽量从很客观的角度尝试去分析。很多比对的结果都是基于实际使用后的感受。不过题主难免会带有一些主观的心理以及了解的片面性,尤其是Drools现在已经更新到了8.X。

规则引擎的定义

首先我想明确下规则引擎的定义,因为很多小伙伴容易把规则引擎和流程引擎的概念混在一起。

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

简单来说就是,规则引擎主要解决易变逻辑和业务耦合的问题,规则驱动逻辑。以前项目内写死在代码里的逻辑用规则引擎可以提出来,随时热变更。

而流程引擎实现了将多个业务参与者之间按照某种预定义的规则进行流转,通常需要涉及到角色信息。

简单来说就是,流程引擎主要解决业务在不同角色之间的流转问题,如请假流程,审批流程,往往要经过多个角色。规则驱动角色流转。

两款框架的异同点

Drools和LiteFlow都是优秀的开源框架,都能把业务中的逻辑给剥离出来。并且拥有自己表达式语法。

但是有所区别的是,Drools强调逻辑的片段规则化,你可以把核心易变部分写成一个规则文件,等同于原先写在java里的代码现在搬迁到了规则文件。规则文件里的代码全都是可以热变更的。

而LiteFlow是基于组件式的思想设计的,更强调组件的规则化,覆盖范围是整个业务。编排的最小单位是组件,规则文件用来串联组件间的流转。同时LiteFlow也支持片段式的代码规则化,因为LiteFlow也支持业务逻辑的脚本化。规则支持热变更。

所以评判一个规则引擎是否合格的主要因素有:

  1. 有没有灵活的规则表达式来支持

  2. 规则和Java之间能否非常方便的联动

  3. API调用是否方便,和各种场景系统的集成如何

  4. 侵入性耦合比较

  5. 规则的学习成本,是否容易上手

  6. 规则表达式是否有语言插件

  7. 规则能否和业务松耦合,存储于其他地方

  8. 规则的变更能否实时改变逻辑

  9. 是否有界面形态来支持非技术人员的使用

  10. 框架的性能表现

下面就从这几个方面来细细比较两款框架的表现力

规则表达式

Drools的规则表达式为Java量身定制的基于Charles Forgy的RETE算法的规则引擎的实现。

Drools的规则表达式贴近自然编程语言,拥有自己的扩展名文件drl,语法支持全,基本上自然编程语言有的语法drl全有。所以,完全可以把java的逻辑写在drl文件中。

来看下drl文件的大体样子:

0cbda500c211faa96a38e3e6824e4576.jpeg

图片

drl文件

可以看到,Drools定义规则的方式是一个规则一段,有明确的when...then,表示当满足什么条件时,做什么。在触发规则时候,会自动判断该去执行哪一段rule,如果满足多个条件,是可以触发多个规则的then的。

LiteFlow编排表达式简单易懂,底层用EL表达式语言包装而成。用于组件的流转,支持异步,选择,条件,循环,嵌套等一些场景。

组件层面不仅可以是java组件,还可以用脚本语言来编写,目前支持了Groovy和QLExpress两种脚本语言。所有能用java实现的,用脚本语言都可以做到。

LiteFlow的规则文件大体长这个样子:

b572c6429320cc0de03f8d4643d3b886.jpeg

图片

LiteFlow的规则文件

上述LiteFlow的编排表达式中,所表达的是下面一个逻辑流:

81ad8062e774bf19c1463a0d49a0c3da.jpeg

图片

LiteFlow的编排表达式

LiteFlow编排表达式支持THEN(同步),WHEN(异步),SWITCH(选择),IF(条件),FOR(次数循环),WHILE(条件循环)等大表达式,每个表达式又有许多扩展关键字可供选用。

脚本组件支持的Groovy基本和java语法差不多,Groovy语言支持的一切你均可使用。甚至可以在Groovy语法中额外定义类和方法。

「结论」

总的来说,两款框架都能用脚本来定义逻辑片段,在定义逻辑片段层面,Drools使用的是自研语法,LiteFlow使用的是插件式的Groovy,其实个人觉得Groovy更接近java语法,你甚至于可以在其中定义类和方法。Drools在高级应用中,也可以用规则定义方法,但是我觉得并不那么自然。

LiteFlow最大的特点是除了定义逻辑片段外,还可以进行全局组件的编排。而这正是LiteFlow称之为编排式规则引擎的由来。使用简单的编排语法可以设计出复杂的逻辑流。支持java和脚本混编。

和Java的数据交换

在Drools的规则中,你可以通过import关键字来引入java的一些类包类进行调用。

在LiteFlow的脚本组件中,Groovy也可以通过import 来引入java的任何包来调用。

Drools中,可以直接引用到fact对象。

LiteFlow中,可以直接引用到context对象,context上下文贯穿整个编排链路。

LiteFlow中,通过@ScriptBean注解,你甚至可以把spring上下文中的bean引入进来直接调用。利用这个特性,甚至于可以在脚本中调用rpc,调用数据库dao对象取数据。这个在Drools里面虽然也可以做到,但是要麻烦的多。

「结论」

基本都能满足和java的数据交换需求,但是LiteFlow在场景上支持的显然更加多一点。

API以及集成

在API调用层面,Drools需要去定义KieContainer,KBase,KSession一系列对象。LiteFlow框架只需要使用到LiteFlowExecutor对象。

Drools支持了编程式接入,但是在springboot中需要自己写很多配置类来去集成。

LiteFlow不仅支持了编程式接入,在springboot环境下更是提供了自动装配的starer接入方式,连定义LiteFlowExecutor都不需要,直接从上下文中就可以拿到自动装配后的对象进行调用。

结论

LiteFlow api更加简单,同Springboot集成度更加高。

侵入性耦合比较

Drools需要在java代码里需要用到规则的地方用KSession对象去匹配规则进行调用。规则和java是分离的。在调用层面耦合了KSession调用对象。

LiteFlow的规则和java也是分离的,但是LiteFlow多了组件这一概念,所以在组件层面是需要继承的,但是同时也提供声明式组件的选择,使用声明式的方式耦合相对要减少一些。在调用层面也需要去调用LiteFlowExecutor对象。

「结论」

在耦合度上面,由于LiteFlow提供编排特性,API耦合度相对稍高一些。Drools耦合少一些。

规则的学习成本

Drools的规则学习成本挺高的。由于是自研的规则语法,需要一个很全面的熟悉过程。而且文档全英文。

LiteFlow的编排规则极其简单,如果你不使用脚本组件的话,基本上10分钟即可上手。就算使用了groovy脚本,由于groovy非常类似于java,学习成本也非常少。况且有大量的学习资料可以参阅。

LiteFlow的文档中英文齐全,还有良好的中文社区可以答疑解惑。

结论

在规则学习成本上,Drools的规则学习曲线比LiteFlow高出不止一丁点。

是否有语言插件

Drools在Eclipse和IDEA上均有插件来做语法的高亮,预检查和提示。

LiteFlow在IDEA上有插件来做高亮,预检查和提示。Eclipse上没有。

结论

考虑到使用eclipse的人几乎很少了,基本上2款规则引擎在语言插件上都做到了。

规则的存储

Drools的规则理论上支持你的规则存于任何地方,但这一切都需要你手动去额外完成。自己去存,自己去取。

Drools还有款workbeanch的插件,可以将规则存于workbeanch中。只有这个是不需要自己存取的。

LiteFlow除了本地规则以外,原生支持将规则存储于任何标准SQL的数据库,还原生支持了Nacos,Etcd,zookeeper等注册中心。只需要配置一下即可。除此之外,还提供了扩展接口,方便你自己扩展成任意的存储点。

「结论」

LiteFlow的规则存储支持比Drools丰富的多。

规则的变更能否实时改变逻辑

Drools热刷新规则的方式现在看起来有点傻,它的规则是通过生成jar的方式。然后系统远程动态读取jar包来完成规则刷新的。

而且一定得通过workbench的方式进行规则的热变更。

LiteFlow在这个层面做的高级很多。如果你是用Nacos,Etcd,zookeeper等方式存储,不用做任何事,改变即自动刷新。如果你是SQL数据库存储,或者本地存储。在改变规则之后,需要调用LiteFlow框架提供的一个API进行热变更。2种方式均可热更新。并且在高并发情况下是平滑的。

「结论」

LiteFlow在热更新设计层面比Drools先进很多。

是否有界面形态来支持

Drools有workbench,workbench是一个独立的插件包,提供了web界面编写规则以及fact对象。并提供了检查和部署的能力。但因为Drools主要关心逻辑片段,并不需要提供编排层面的拖拽UI功能,只是提供了在界面上编写规则的能力。

LiteFlow并没有界面形态。目前只能通过第三方的Nacos,Etcd提供的界面来辅助完成界面的规则修改。

「结论」

Drools在UI形态生态上领先LiteFlow一截。

框架的性能表现

这里用Drools和LiteFlow实现了同样的一段逻辑Demo。

根据订单金额来加积分的Demo案例。

案例逻辑很简单,根据订单的金额来动态判断该加多少积分:

小于100元,不加积分。

100到500元,加100积分。

500到1000元,加500积分。

1000元以上,加1000积分。

其中Drools的规则如下:

package rules;

import com.example.droolsdemo.entity.Order;

rule "score_1"
when
    $order:Order(amount<100)
then
    $order.setScore(0);
    System.out.println("触发了规则1");
end

rule "score_2"
when
    $order:Order(amount>=100 && amount < 500)
then
    $order.setScore(100);
    System.out.println("触发了规则2");
end

rule "score_3"
when
    $order:Order(amount>=500 && amount < 1000)
then
    $order.setScore(500);
    System.out.println("触发了规则3");
end

rule "score_4"
when
    $order:Order(amount>=1000)
then
    $order.setScore(1000);
    System.out.println("触发了规则4");
end

其中等价的LiteFlow规则如下:

<?xml version="1.0" encoding="UTF-8"?>
<flow>
    <nodes>
        <node id="w" type="switch_script">
            <![CDATA[
                def amount = defaultContext.getData("order").getAmount();

                if (amount < 100){
                    return "a";
                }else if(amount >= 100 && amount < 500){
                    return "b";
                }else if(amount >= 500 && amount < 1000){
                    return "c";
                }else{
                    return "d";
                }
            ]]>
        </node>

        <node id="a" type="script">
            <![CDATA[
                def order = defaultContext.getData("order");
                order.setScore(0);
                println("执行规则a");
            ]]>
        </node>

        <node id="b" type="script">
            <![CDATA[
                def order = defaultContext.getData("order");
                order.setScore(100);
                println("执行规则b");
            ]]>
        </node>

        <node id="c" type="script">
            <![CDATA[
                def order = defaultContext.getData("order");
                order.setScore(500);
                println("执行规则c");
            ]]>
        </node>

        <node id="d" type="script">
            <![CDATA[
                def order = defaultContext.getData("order");
                order.setScore(1000);
                println("执行规则d");
            ]]>
        </node>
    </nodes>

    <chain name="chain1">
        SWITCH(w).TO(a, b, c, d);
    </chain>
</flow>

两款框架都全用脚本来写的情况下,测试的过程中,去除所有的打印日志,执行10w次,得到的结果如下:

Drools 执行10w次,耗时0.7秒

LiteFlow全脚本组件执行10w次,耗时3.6秒

由于LiteFlow在全脚本组件的情况下,需要做脚本的执行和编排脚本的执行,所以花费的时间更长。

如果LiteFlow把组件更换成java,再进行执行,得到的结果如下:

LiteFlow 全Java组件执行10w次,耗时0.5秒

结论

如果LiteFlow采用全脚本的方式运行,耗时会比Drools更长。如果采用全java组件的方式运行,其性能能超越Drools一点。

所以对于LiteFlow而言,如果你希望更高的性能,则采用java组件,如果你希望更高的灵活性,则采用脚本组件。

其实在实际业务中,把容易更改的逻辑抽出来写成脚本组件,采用java+脚本混编的方式,是更为推荐的做法。

结语

为什么会拿Drools来作为比较,其一在题主心中,Drools一直是规则引擎界的标杆,drools有很多理念非常值得学习。其二也是因为题主也只熟悉Drools,其他的框架没有很好的使用过的缘故。

但是综合来看,作为国产规则引擎后起之秀LiteFlow显然在设计理念,支持度方面是要优于Drools的。编排式规则引擎作为规则引擎的一个新的方向,也会一直探索下去的。希望大家能多多支持这款国产的规则引擎。在编排方向,LiteFlow除了文中所提到的一些特性以外,还有很多其他各种各样的探索性的玩法和高级特性。是一款很值得深挖的框架。

👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 /  赠书福利

全栈前后端分离博客项目 2.0 版本完结啦, 演示链接http://116.62.199.48/ ,新项目正在酝酿中。全程手摸手,后端 + 前端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,直到项目上线。目前已更新了239小节,累计38w+字,讲解图:1645张,还在持续爆肝中.. 后续还会上新更多项目,目标是将Java领域典型的项目都整一波,如秒杀系统, 在线商城, IM即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,已有1200+小伙伴加入(早鸟价超低)

7a980927da4f64bbfb6d41a66d553091.gif

40f7ba61599ac54660d90a51529cd038.jpeg

 
 

3353a9246f86a0e53de76e26a71c205b.gif

 
 
 
 
1. 我的私密学习小圈子~
2. 工作中如何体现一个人的技术深度?
3. Redis缓存预热,该如何实现?
4. 为什么 SQL 中要尽量避免使用 IN 和 NOT IN?
 
 
最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。
PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。
点“在看”支持小哈呀,谢谢啦
<think>好的,用户需要一个规则引擎来支持可视化配置规则,输出预警和数据稽核结果。需要从DroolsLiteFlow、Easy Rules、JRule、OpenL、URule、Aviator这几个选项中选合适的。 首先,我应该先理清楚用户的主要需求:可视化配置规则是关键,还有需要处理预警和数据稽核的结果。接下来,我需要逐一分析每个规则引擎的特点,看看哪些支持可视化配置,以及是否符合其他需求。 Drools是常用的规则引擎,功能强大,但可视化方面可能需要用KIE Workbench,这可能有点复杂,学习成本高。对于需要快速上手的用户来说可能不太合适,但如果项目复杂度高,Drools还是可以考虑的。 LiteFlow主要处理流程编排,规则编排能力不错,有简单的可视化界面,但更侧重于流程控制。如果用户的需求不仅仅是规则执行,还涉及复杂流程,可能适合,但不确定其可视化配置是否足够强大。 Easy Rules轻量级,适合简单场景,但缺乏可视化界面,可能不符合用户的可视化需求,排除。 JRule是基于Java的,用注解定义规则,但同样没有可视化支持,排除。 OpenL Tablets基于Excel,规则管理方便,但可视化可能不够灵活,适合喜欢用Excel的用户,但可能不是最佳选择。 URule有强大的Web可视化配置,支持决策表、决策树等,还提供调试和版本管理,非常适合需要可视化配置的用户,预警和数据稽核应该可以处理。但开源版功能有限,商用需要付费。 Aviator是表达式引擎,处理表达式快,但不支持可视化配置,排除。 综合来看,URule和Drools(结合KIE Workbench)比较符合需求。URule的可视化更友好,适合国内用户,但需要考虑商业授权。Drools虽然功能强,但可能需要更多开发工作。如果用户需要开源免费,可能需要折中,比如Drools配合其他工具实现可视化,或者选择LiteFlow的简单可视化。但URule在可视化方面最符合,所以优先推荐URule,其次是DroolsLiteFlow,根据项目具体情况选择。</think>根据可视化配置和稽核预警需求,推荐采用如下技术选型方案: 一、首选方案:URule (推荐指数★★★★★) 1. 核心优势: - 提供完整的Web可视化规则设计器(决策表/决策树/评分卡/决策流) - 支持实时调试和版本控制功能 - 内置规则校验与冲突检测机制 - 支持多维度的数据稽核结果统计报表 - 中文文档和技术支持较为完善 2. 预警实现方案: ```java // 创建预警规则示例 rule "账户异常预警" salience 9 when $acc:Account(balance < 0, lastUpdateTime before[30d]) then insert(new Alert("E1001", "账户透支超期预警", $acc)); end ``` 3. 数据稽核示例: ```java rule "销售数据校验" when $order:Order(totalAmount != (itemAmount + tax)) then auditService.logError($order, "金额计算不一致"); end ``` 二、备选方案:Drools + KIE Workbench (推荐指数★★★★☆) 1. 组合优势: - 企业级规则引擎稳定性强 - 支持决策表等可视化配置 - 丰富的规则语法体系 2. 可视化配置流程: ``` 业务人员登录KIE Workbench → 创建数据对象 → 设计决策表 → 发布知识包 → 系统通过REST API调用 ``` 三、轻量级方案:LiteFlow (推荐指数★★★☆☆) 1. 适用场景: - 需要与现有管理系统深度整合 - 规则变更频繁但复杂度中等 - 需要快速实现可视化配置原型 2. 可视化开发示例: ```xml <chain name="riskControl"> <component value="BalanceCheck"/> <component value="FrequencyCheck"/> <component value="FinalDecision"/> </chain> ``` 四、选型对照表: | 引擎 | 可视化支持 | 学习曲线 | 预警能力 | 稽核报表 | 开源协议 | |------------|------------|----------|----------|----------|-------------| | URule | ★★★★★ | 中等 | ★★★★★ | ★★★★★ | 商业授权 | | Drools | ★★★★☆ | 陡峭 | ★★★★☆ | ★★★★☆ | Apache 2.0 | | LiteFlow | ★★★☆☆ | 平缓 | ★★★☆☆ | ★★★☆☆ | Apache 2.0 | | Aviator | ☆☆☆☆☆ | 简单 | ★★☆☆☆ | ★☆☆☆☆ | Apache 2.0 | 五、实施建议: 1. 优先考虑URule进行PoC验证,建议申请试用版评估以下功能: - 规则版本对比工具 - 批量测试用例验证 - 分布式规则热部署 - 审计日志追踪能力 2. 对于需要深度定制的场景,可采用Drools+自定义前端方案: ```javascript // 自定义规则设计器示例 class RuleDesigner { buildCondition(field, operator, value) { return `$${field}: ${field.type} ${operator} ${value}` } generateDRL(rules) { return rules.map(r => `rule "${r.name}"\n` + `when\n ${r.condition}\n` + `then\n ${r.action}\nend` ).join('\n\n') } } ``` 3. 对于实时性要求高的场景,建议结合Aviator做表达式计算: ```java // 快速计算示例 Map<String, Object> env = new HashMap<>(); env.put("amount", 1500); Boolean result = (Boolean) AviatorEvaluator.execute("amount > 1000 && amount < 5000", env); ``` 根据实际项目预算、团队技术栈、性能要求(建议基准测试QPS>2000)等因素综合决策,可组合使用多种引擎构建分层的规则处理体系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值