Drools是一款老牌的java規(guī)則引擎框架,早在十幾年前,我剛工作的時(shí)候,曾在一家第三方支付企業(yè)工作。在核心的支付路由層面我記得就是用Drools來做的。
難能可貴的是,Drools這個(gè)項(xiàng)目在十幾年后還依舊保持著開源和更新。
而LiteFlow也是一款java規(guī)則引擎,于2020年開源。經(jīng)過2年的迭代,現(xiàn)在功能和特性也非常棒,很適合用在高復(fù)雜度的核心業(yè)務(wù)上,同時(shí)又能保持業(yè)務(wù)的靈活性。
這篇文章我們就來深入比較下這兩款框架,都適合用在什么樣的場景,有什么異同點(diǎn),以及在相同的場景下表現(xiàn)力如何。
(其中Drools基于7.6.0版本,LiteFlow基于2.9.0版本)
雖然題主就是開源項(xiàng)目LiteFlow的作者,但是我這幾天也深入了解了下Drools,盡量從很客觀的角度嘗試去分析。很多比對的結(jié)果都是基于實(shí)際使用后的感受。不過題主難免會帶有一些主觀的心理以及了解的片面性,尤其是Drools現(xiàn)在已經(jīng)更新到了8.X。
規(guī)則引擎的定義
首先我想明確下規(guī)則引擎的定義,因?yàn)楹芏嘈』锇槿菀装岩?guī)則引擎和流程引擎的概念混在一起。
規(guī)則引擎通常是嵌入在應(yīng)用程序組件中的,實(shí)現(xiàn)了將業(yè)務(wù)決策從應(yīng)用程序代碼中分離出來,并使用預(yù)定義的語義模塊編寫業(yè)務(wù)決策。接受數(shù)據(jù)輸入,解釋業(yè)務(wù)規(guī)則,并根據(jù)業(yè)務(wù)規(guī)則做出業(yè)務(wù)決策。
簡單來說就是,規(guī)則引擎主要解決易變邏輯和業(yè)務(wù)耦合的問題,規(guī)則驅(qū)動邏輯。以前項(xiàng)目內(nèi)寫死在代碼里的邏輯用規(guī)則引擎可以提出來,隨時(shí)熱變更。
而流程引擎實(shí)現(xiàn)了將多個(gè)業(yè)務(wù)參與者之間按照某種預(yù)定義的規(guī)則進(jìn)行流轉(zhuǎn),通常需要涉及到角色信息。
簡單來說就是,流程引擎主要解決業(yè)務(wù)在不同角色之間的流轉(zhuǎn)問題,如請假流程,審批流程,往往要經(jīng)過多個(gè)角色。規(guī)則驅(qū)動角色流轉(zhuǎn)。
兩款框架的異同點(diǎn)
Drools和LiteFlow都是優(yōu)秀的開源框架,都能把業(yè)務(wù)中的邏輯給剝離出來。并且擁有自己表達(dá)式語法。
但是有所區(qū)別的是,Drools強(qiáng)調(diào)邏輯的片段規(guī)則化,你可以把核心易變部分寫成一個(gè)規(guī)則文件,等同于原先寫在java里的代碼現(xiàn)在搬遷到了規(guī)則文件。規(guī)則文件里的代碼全都是可以熱變更的。
而LiteFlow是基于組件式的思想設(shè)計(jì)的,更強(qiáng)調(diào)組件的規(guī)則化,覆蓋范圍是整個(gè)業(yè)務(wù)。編排的最小單位是組件,規(guī)則文件用來串聯(lián)組件間的流轉(zhuǎn)。同時(shí)LiteFlow也支持片段式的代碼規(guī)則化,因?yàn)長iteFlow也支持業(yè)務(wù)邏輯的腳本化。規(guī)則支持熱變更。
所以評判一個(gè)規(guī)則引擎是否合格的主要因素有:
有沒有靈活的規(guī)則表達(dá)式來支持
規(guī)則和Java之間能否非常方便的聯(lián)動
API調(diào)用是否方便,和各種場景系統(tǒng)的集成如何
侵入性耦合比較
規(guī)則的學(xué)習(xí)成本,是否容易上手
規(guī)則表達(dá)式是否有語言插件
規(guī)則能否和業(yè)務(wù)松耦合,存儲于其他地方
規(guī)則的變更能否實(shí)時(shí)改變邏輯
是否有界面形態(tài)來支持非技術(shù)人員的使用
框架的性能表現(xiàn)
下面就從這幾個(gè)方面來細(xì)細(xì)比較兩款框架的表現(xiàn)力
規(guī)則表達(dá)式
Drools的規(guī)則表達(dá)式為Java量身定制的基于Charles Forgy的RETE算法的規(guī)則引擎的實(shí)現(xiàn)。
Drools的規(guī)則表達(dá)式貼近自然編程語言,擁有自己的擴(kuò)展名文件drl,語法支持全,基本上自然編程語言有的語法drl全有。所以,完全可以把java的邏輯寫在drl文件中。
來看下drl文件的大體樣子:

drl文件
可以看到,Drools定義規(guī)則的方式是一個(gè)規(guī)則一段,有明確的when...then,表示當(dāng)滿足什么條件時(shí),做什么。關(guān)注公z號:碼猿技術(shù)專欄,回復(fù)關(guān)鍵詞:1111 獲取阿里內(nèi)部Java性能優(yōu)化手冊!在觸發(fā)規(guī)則時(shí)候,會自動判斷該去執(zhí)行哪一段rule,如果滿足多個(gè)條件,是可以觸發(fā)多個(gè)規(guī)則的then的。
LiteFlow編排表達(dá)式簡單易懂,底層用EL表達(dá)式語言包裝而成。用于組件的流轉(zhuǎn),支持異步,選擇,條件,循環(huán),嵌套等一些場景。
組件層面不僅可以是java組件,還可以用腳本語言來編寫,目前支持了Groovy和QLExpress兩種腳本語言。所有能用java實(shí)現(xiàn)的,用腳本語言都可以做到。
LiteFlow的規(guī)則文件大體長這個(gè)樣子:

LiteFlow的規(guī)則文件
上述LiteFlow的編排表達(dá)式中,所表達(dá)的是下面一個(gè)邏輯流:

LiteFlow的編排表達(dá)式
LiteFlow編排表達(dá)式支持THEN(同步),WHEN(異步),SWITCH(選擇),IF(條件),F(xiàn)OR(次數(shù)循環(huán)),WHILE(條件循環(huán))等大表達(dá)式,每個(gè)表達(dá)式又有許多擴(kuò)展關(guān)鍵字可供選用。
腳本組件支持的Groovy基本和java語法差不多,Groovy語言支持的一切你均可使用。甚至可以在Groovy語法中額外定義類和方法。
「結(jié)論」
總的來說,兩款框架都能用腳本來定義邏輯片段,在定義邏輯片段層面,Drools使用的是自研語法,LiteFlow使用的是插件式的Groovy,其實(shí)個(gè)人覺得Groovy更接近java語法,你甚至于可以在其中定義類和方法。Drools在高級應(yīng)用中,也可以用規(guī)則定義方法,但是我覺得并不那么自然。
LiteFlow最大的特點(diǎn)是除了定義邏輯片段外,還可以進(jìn)行全局組件的編排。而這正是LiteFlow稱之為編排式規(guī)則引擎的由來。使用簡單的編排語法可以設(shè)計(jì)出復(fù)雜的邏輯流。支持java和腳本混編。
和Java的數(shù)據(jù)交換
在Drools的規(guī)則中,你可以通過import關(guān)鍵字來引入java的一些類包類進(jìn)行調(diào)用。
在LiteFlow的腳本組件中,Groovy也可以通過import 來引入java的任何包來調(diào)用。
Drools中,可以直接引用到fact對象。
LiteFlow中,可以直接引用到context對象,context上下文貫穿整個(gè)編排鏈路。
LiteFlow中,通過@ScriptBean注解,你甚至可以把spring上下文中的bean引入進(jìn)來直接調(diào)用。利用這個(gè)特性,甚至于可以在腳本中調(diào)用rpc,調(diào)用數(shù)據(jù)庫dao對象取數(shù)據(jù)。這個(gè)在Drools里面雖然也可以做到,但是要麻煩的多。
「結(jié)論」
基本都能滿足和java的數(shù)據(jù)交換需求,但是LiteFlow在場景上支持的顯然更加多一點(diǎn)。
API以及集成
在API調(diào)用層面,Drools需要去定義KieContainer,KBase,KSession一系列對象。LiteFlow框架只需要使用到LiteFlowExecutor對象。
Drools支持了編程式接入,但是在springboot中需要自己寫很多配置類來去集成。
LiteFlow不僅支持了編程式接入,在springboot環(huán)境下更是提供了自動裝配的starer接入方式,連定義LiteFlowExecutor都不需要,直接從上下文中就可以拿到自動裝配后的對象進(jìn)行調(diào)用。
結(jié)論
LiteFlow api更加簡單,同Springboot集成度更加高。
侵入性耦合比較
Drools需要在java代碼里需要用到規(guī)則的地方用KSession對象去匹配規(guī)則進(jìn)行調(diào)用。規(guī)則和java是分離的。在調(diào)用層面耦合了KSession調(diào)用對象。
LiteFlow的規(guī)則和java也是分離的,但是LiteFlow多了組件這一概念,所以在組件層面是需要繼承的,但是同時(shí)也提供聲明式組件的選擇,使用聲明式的方式耦合相對要減少一些。在調(diào)用層面也需要去調(diào)用LiteFlowExecutor對象。
「結(jié)論」
在耦合度上面,由于LiteFlow提供編排特性,API耦合度相對稍高一些。Drools耦合少一些。
規(guī)則的學(xué)習(xí)成本
Drools的規(guī)則學(xué)習(xí)成本挺高的。由于是自研的規(guī)則語法,需要一個(gè)很全面的熟悉過程。而且文檔全英文。
LiteFlow的編排規(guī)則極其簡單,如果你不使用腳本組件的話,基本上10分鐘即可上手。就算使用了groovy腳本,由于groovy非常類似于java,學(xué)習(xí)成本也非常少。況且有大量的學(xué)習(xí)資料可以參閱。
LiteFlow的文檔中英文齊全,還有良好的中文社區(qū)可以答疑解惑。
結(jié)論
在規(guī)則學(xué)習(xí)成本上,Drools的規(guī)則學(xué)習(xí)曲線比LiteFlow高出不止一丁點(diǎn)。
是否有語言插件
Drools在Eclipse和IDEA上均有插件來做語法的高亮,預(yù)檢查和提示。
LiteFlow在IDEA上有插件來做高亮,預(yù)檢查和提示。Eclipse上沒有。
結(jié)論
考慮到使用eclipse的人幾乎很少了,基本上2款規(guī)則引擎在語言插件上都做到了。
規(guī)則的存儲
Drools的規(guī)則理論上支持你的規(guī)則存于任何地方,但這一切都需要你手動去額外完成。自己去存,自己去取。
Drools還有款workbeanch的插件,可以將規(guī)則存于workbeanch中。只有這個(gè)是不需要自己存取的。
LiteFlow除了本地規(guī)則以外,原生支持將規(guī)則存儲于任何標(biāo)準(zhǔn)SQL的數(shù)據(jù)庫,還原生支持了Nacos,Etcd,zookeeper等注冊中心。只需要配置一下即可。除此之外,還提供了擴(kuò)展接口,方便你自己擴(kuò)展成任意的存儲點(diǎn)。
「結(jié)論」
LiteFlow的規(guī)則存儲支持比Drools豐富的多。
規(guī)則的變更能否實(shí)時(shí)改變邏輯
Drools熱刷新規(guī)則的方式現(xiàn)在看起來有點(diǎn)傻,它的規(guī)則是通過生成jar的方式。然后系統(tǒng)遠(yuǎn)程動態(tài)讀取jar包來完成規(guī)則刷新的。
而且一定得通過workbench的方式進(jìn)行規(guī)則的熱變更。
LiteFlow在這個(gè)層面做的高級很多。如果你是用Nacos,Etcd,zookeeper等方式存儲,不用做任何事,改變即自動刷新。如果你是SQL數(shù)據(jù)庫存儲,或者本地存儲。在改變規(guī)則之后,需要調(diào)用LiteFlow框架提供的一個(gè)API進(jìn)行熱變更。2種方式均可熱更新。并且在高并發(fā)情況下是平滑的。
「結(jié)論」
LiteFlow在熱更新設(shè)計(jì)層面比Drools先進(jìn)很多。
是否有界面形態(tài)來支持
Drools有workbench,workbench是一個(gè)獨(dú)立的插件包,提供了web界面編寫規(guī)則以及fact對象。并提供了檢查和部署的能力。但因?yàn)镈rools主要關(guān)心邏輯片段,并不需要提供編排層面的拖拽UI功能,只是提供了在界面上編寫規(guī)則的能力。
LiteFlow并沒有界面形態(tài)。目前只能通過第三方的Nacos,Etcd提供的界面來輔助完成界面的規(guī)則修改。
「結(jié)論」
Drools在UI形態(tài)生態(tài)上領(lǐng)先LiteFlow一截。
框架的性能表現(xiàn)
這里用Drools和LiteFlow實(shí)現(xiàn)了同樣的一段邏輯Demo。
根據(jù)訂單金額來加積分的Demo案例。
案例邏輯很簡單,根據(jù)訂單的金額來動態(tài)判斷該加多少積分:
小于100元,不加積分。
100到500元,加100積分。
500到1000元,加500積分。
1000元以上,加1000積分。
其中Drools的規(guī)則如下:
packagerules; importcom.example.droolsdemo.entity.Order; rule"score_1" when $order:Order(amount<100) then ????$order.setScore(0); ????System.out.println("觸發(fā)了規(guī)則1"); end rule?"score_2" when ????$order:Order(amount>=100&&amount500) then ????$order.setScore(100); ????System.out.println("觸發(fā)了規(guī)則2"); end rule?"score_3" when ????$order:Order(amount>=500&&amount1000) then ????$order.setScore(500); ????System.out.println("觸發(fā)了規(guī)則3"); end rule?"score_4" when ????$order:Order(amount>=1000) then $order.setScore(1000); System.out.println("觸發(fā)了規(guī)則4"); end
其中等價(jià)的LiteFlow規(guī)則如下:
=100&&amount500){ ????????????????????return?"b"; ????????????????}else?if(amount?>=500&&amount1000){ ????????????????????return?"c"; ????????????????}else{ ????????????????????return?"d"; ????????????????} ????????????]]> SWITCH(w).TO(a,b,c,d);
兩款框架都全用腳本來寫的情況下,測試的過程中,去除所有的打印日志,執(zhí)行10w次,得到的結(jié)果如下:
Drools 執(zhí)行10w次,耗時(shí)0.7秒
LiteFlow全腳本組件執(zhí)行10w次,耗時(shí)3.6秒
由于LiteFlow在全腳本組件的情況下,需要做腳本的執(zhí)行和編排腳本的執(zhí)行,所以花費(fèi)的時(shí)間更長。
如果LiteFlow把組件更換成java,再進(jìn)行執(zhí)行,得到的結(jié)果如下:
LiteFlow 全Java組件執(zhí)行10w次,耗時(shí)0.5秒
結(jié)論
如果LiteFlow采用全腳本的方式運(yùn)行,耗時(shí)會比Drools更長。如果采用全java組件的方式運(yùn)行,其性能能超越Drools一點(diǎn)。
所以對于LiteFlow而言,如果你希望更高的性能,則采用java組件,如果你希望更高的靈活性,則采用腳本組件。
其實(shí)在實(shí)際業(yè)務(wù)中,把容易更改的邏輯抽出來寫成腳本組件,采用java+腳本混編的方式,是更為推薦的做法。
結(jié)語
為什么會拿Drools來作為比較,其一在題主心中,Drools一直是規(guī)則引擎界的標(biāo)桿,drools有很多理念非常值得學(xué)習(xí)。其二也是因?yàn)轭}主也只熟悉Drools,其他的框架沒有很好的使用過的緣故。
但是綜合來看,作為國產(chǎn)規(guī)則引擎后起之秀LiteFlow顯然在設(shè)計(jì)理念,支持度方面是要優(yōu)于Drools的。編排式規(guī)則引擎作為規(guī)則引擎的一個(gè)新的方向,也會一直探索下去的。希望大家能多多支持這款國產(chǎn)的規(guī)則引擎。在編排方向,LiteFlow除了文中所提到的一些特性以外,還有很多其他各種各樣的探索性的玩法和高級特性。是一款很值得深挖的框架。
審核編輯:劉清
-
JAVA
+關(guān)注
關(guān)注
20文章
3001瀏覽量
116436 -
RPC
+關(guān)注
關(guān)注
0文章
114瀏覽量
12264 -
編程語言
+關(guān)注
關(guān)注
10文章
1964瀏覽量
39573 -
API接口
+關(guān)注
關(guān)注
1文章
114瀏覽量
11248
原文標(biāo)題:規(guī)則引擎深度對比,LiteFlow vs Drools!
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
UV膠和環(huán)氧樹脂膠區(qū)別:固化方式、性能深度對比 |鉻銳特實(shí)業(yè)
工程師之夜系列分享第三十九篇:Kafka、RocketMQ、JMQ 存儲架構(gòu)深度對比
資料] 汽車軟件質(zhì)量躍遷的系統(tǒng)性路徑:基于ISO 26262標(biāo)準(zhǔn)的單元測試體系重構(gòu)與中日實(shí)踐深度對比(2026學(xué)術(shù)研究報(bào)告)
糾結(jié)選國產(chǎn)還是進(jìn)口?華潤微7388 vs 進(jìn)口TDA7388 實(shí)戰(zhàn)對比
暴力實(shí)測!7388 vs 進(jìn)口同級別芯片,3大維度碾壓,價(jià)格卻省一半
不間斷電源怎么選?蓄電池VS UPS深度對比,看完省下30%預(yù)算!
信而泰×DeepSeek:AI推理引擎驅(qū)動網(wǎng)絡(luò)智能診斷邁向 “自愈”時(shí)代
CES Asia 2025 低空經(jīng)濟(jì)專館:思想碰撞,引領(lǐng)低空經(jīng)濟(jì)規(guī)則升級
主流版本控制工具Git vs Perforce P4:架構(gòu)模式、性能、大文件管理及分支管理對比詳解
小米玄戒O1 vs 蘋果A18 全面對比分析
接地電阻柜vs其他接地方式對比
泰克3系與5系示波器存儲深度對比測試
規(guī)則引擎深度對比,LiteFlow vs Drools!
評論