一、產(chǎn)生的背景
生產(chǎn)過程中,線上的業(yè)務(wù)規(guī)則內(nèi)嵌在系統(tǒng)的各處代碼中,每次策略的調(diào)整都需要更新線上系統(tǒng),進(jìn)行從需求->設(shè)計->編碼->測試->上線這種長周期的流程,滿足不了業(yè)務(wù)規(guī)則的快速變化以及低成本的更新試錯迭代。
因此需要有一種解決方案將商業(yè)決策邏輯和應(yīng)用開發(fā)者的技術(shù)決策分離開,在系統(tǒng)運行時能去更新管理業(yè)務(wù)規(guī)則。
規(guī)則引擎(業(yè)務(wù)規(guī)則管理系統(tǒng),英文名為BRMS(即Business Rule Management System))正是這樣的解決方案。
二、實際業(yè)務(wù)場景:
一個小例子: 假如我們有個業(yè)務(wù)場景,當(dāng)客戶的積分位于一個區(qū)間A時,我們給予他一個頭銜a,當(dāng)一個客戶的積分位于區(qū)間B時,我們給予他一個頭銜b,當(dāng)客戶的積分位于區(qū)間C時,我們給予他一個 頭銜c。如果我們使用if-else-then來寫,是可以實現(xiàn)的,但是這里存在一個問題:規(guī)則定義和代碼耦合在一起了。如果我們改變規(guī)則,把區(qū)間A,B,C 改成D,E,F(xiàn),又或是將規(guī)則增加,從3組變?yōu)?00組,那么我們改代碼實在是太麻煩了。這時候規(guī)則引擎就派上用場了,我們希望把規(guī)則和代碼解耦,形成一個規(guī)則引擎,以適應(yīng)復(fù)雜多變的業(yè)務(wù)場景,或者更加精細(xì)化的運營。
??實際業(yè)務(wù)場景:
BD績效考核是將各個戰(zhàn)區(qū)每月針對bd制定的績效考核方案線上化,支持績效方案設(shè)置、bd績效達(dá)成情況跟蹤、績效薪資計算等功能。
現(xiàn)狀: 績效的考核方案和激勵政策呈現(xiàn)出多樣化、復(fù)雜化的特點,不同的戰(zhàn)區(qū)績效考核的指標(biāo)及考核方案不同,每個戰(zhàn)區(qū)每個月的指標(biāo)及考核方案變化非常大,同一個指標(biāo)每月對應(yīng)的規(guī)則定義不同。
方案: 為了應(yīng)對戰(zhàn)區(qū)績效考核方案多變,本次需要實現(xiàn)指標(biāo)規(guī)則的靈活配置。
以有效團(tuán)長數(shù)為例:
有效團(tuán)長定義為: 團(tuán)長每月有效團(tuán)達(dá)標(biāo)天數(shù)>=15天(有效團(tuán)指的是每天成團(tuán)的標(biāo)準(zhǔn):5個下單用戶,15件下單商品)
指標(biāo)類型 | 指標(biāo)名稱 | 指標(biāo)規(guī)則 | 實體 | 時間維度 |
---|---|---|---|---|
原子指標(biāo) | 團(tuán)用戶數(shù) | 團(tuán)成交用戶數(shù) | 團(tuán) | 日 |
原子指標(biāo) | 團(tuán)商品數(shù) | 團(tuán)成交商品數(shù) | 團(tuán) | 日 |
復(fù)合指標(biāo) | 是否有效團(tuán) | 團(tuán)用戶數(shù)>=5且團(tuán)商品數(shù)>=15 | 團(tuán) | 日 |
復(fù)合指標(biāo) | 有效團(tuán)天數(shù) | 是否有效團(tuán)=1,求和sum | 團(tuán)長 | 月 |
復(fù)合指標(biāo) | 是否有效團(tuán)長 | 有效團(tuán)天數(shù)>=15天 | 團(tuán)長 | 月 |
復(fù)合指標(biāo) | 有效團(tuán)長數(shù) | 是否有效團(tuán)長=1,求和sum | 組織/網(wǎng)格 | 月 |
三、規(guī)則引擎價值及本質(zhì)
3.1 規(guī)則引擎價值:
最大的價值就在于通過以下的三個過程,大大的緩解了頻繁的需求變化給整個業(yè)務(wù)系統(tǒng)帶來的災(zāi)難。
-
逼迫系統(tǒng)開發(fā)人員和業(yè)務(wù)專家梳理業(yè)務(wù),定義統(tǒng)一的BOM(業(yè)務(wù)對象模型)。
-
業(yè)務(wù)專家可以快速的制定修改規(guī)則,然后交由規(guī)則引擎自動化地來處理分析。
-
規(guī)則引擎代替系統(tǒng)開發(fā)人員,解決由規(guī)則條件關(guān)聯(lián)動作變化帶來的開發(fā)工作。
總結(jié)一句話:規(guī)則引擎就是將需要外部決策的業(yè)務(wù)規(guī)則加載到系統(tǒng)中,按照不同的輸入條件進(jìn)行不同的規(guī)則匹配組合后,執(zhí)行符合規(guī)則的一個或者多個操作。
3.2 規(guī)則引擎的本質(zhì)
本質(zhì)是“專家決策系統(tǒng)規(guī)則引擎模型”和rete算法,為了解決的是大量重復(fù)的condition匹配效率的問題,以及規(guī)則沖突規(guī)范的問題,和腳本的性能比較不在同一個層面上。
四、 Rete算法介紹
(1)規(guī)則內(nèi)容
IF:
年級是三年級以上,
性別是男的,
年齡小于10歲,
身體健壯,
身高170cm以上,
THEN:
這個男孩是一個籃球苗子,需要培養(yǎng)
網(wǎng)絡(luò)構(gòu)建:
匹配過程:
(1)匹配過程中事實在網(wǎng)絡(luò)節(jié)點中的流轉(zhuǎn)順序為A-->B-->C-->D-->E-->F-->G-->H-->I--->規(guī)則匹配通過
(2)從working-Memory中拿出一個待匹配的StudentFact對象,進(jìn)入根節(jié)點然后進(jìn)行匹配,以下是fact在各個節(jié)點中的活動圖
A節(jié)點:拿StudentFact的年級數(shù)值進(jìn)行年級匹配,如果年級符合條件,則把該StudentFact的引用記錄到A節(jié)點的alpha內(nèi)存區(qū)中,退出年級匹配。
B節(jié)點:拿StudentFact的性別內(nèi)容進(jìn)行性別匹配,如果性別符合條件,則把該StudentFact的引用記錄到B節(jié)點的alpha內(nèi)存區(qū)中,然后找到B節(jié)點左引用的Beta節(jié)點,也就是C節(jié)點。
C節(jié)點:C節(jié)點找到自己的左引用也就是A節(jié)點,看看A節(jié)點的alpha內(nèi)存區(qū)中是否存放了StudentFact的引用,如果存放,說明年級和性別兩個條件都符合,則在C節(jié)點的Beta內(nèi)存區(qū)中存放StudentFact的引用,退出性別匹配。
D節(jié)點:拿StudentFact的年齡數(shù)值進(jìn)行年齡條件匹配,如果年齡符合條件,則把該StudentFact的引用記錄到D節(jié)點的alpha的內(nèi)存區(qū)中,然后找到D節(jié)點的左引用的Beta節(jié)點,也就是E節(jié)點。
E節(jié)點:E節(jié)點找到自己的左引用也就是C節(jié)點,看看C節(jié)點的Beta內(nèi)存區(qū)中是否存放了StudentFact的引用,如果存放,說明年級,性別,年齡三個條件符合,則在E節(jié)點的Beta內(nèi)存區(qū)中存放StudentFact的引用,退出年齡匹配。
F節(jié)點:拿StudentFact的身體數(shù)值進(jìn)行身體條件匹配,如果身體條件符合,則把該StudentFact的引用記錄到D節(jié)點的alpha的內(nèi)存區(qū)中,然后找到F節(jié)點的左引用的Beta節(jié)點,也就是G節(jié)點。
G節(jié)點:G節(jié)點找到自己的左引用也就是E節(jié)點,看看E節(jié)點的Beta內(nèi)存區(qū)中是否存放了StudentFact的引用,如果存放,說明年級,性別,年齡,身體四個條件符合,則在G節(jié)點的Beta內(nèi)存區(qū)中存放StudentFact的引用,退出身體匹配
H節(jié)點:拿StudentFact的身高數(shù)值進(jìn)行身高條件匹配,如果身高條件符合,則把該StudentFact的引用記錄到H節(jié)點的alpha的內(nèi)存區(qū)中,然后找到H節(jié)點的左引用的Beta節(jié)點,也就是I節(jié)點。
I節(jié)點:I節(jié)點找到自己的左引用也就是G節(jié)點,看看G節(jié)點的Beta內(nèi)存區(qū)中是否存放了StudentFact的引用,如果存放了,說明年級,性別,年齡,身體,身高五個條件都符合,則在I節(jié)點的Beta內(nèi)存區(qū)中存放StudentFact引用。
同時說明該StudentFact對象匹配了該規(guī)則,形成一個議程,加入到?jīng)_突區(qū),執(zhí)行該條件的結(jié)果部分:該學(xué)生是一個籃球苗子。
五、Rete算法優(yōu)劣勢分析
5.1 Rete算法優(yōu)于傳統(tǒng)的模式匹配算法
a.狀態(tài)保存。 Rete 算法是一種啟發(fā)式算法,不同規(guī)則之間往往含有相同的模式,因此在 beta-network 中可以共享 BetaMemory 和 betanode。如果某個 betanode 被 N 條規(guī)則共享,則算法在此節(jié)點上效率會提高 N 倍。
b. 節(jié)點共享。 Rete 算法由于采用 AlphaMemory 和 BetaMemory 來存儲事實,當(dāng)事實集合變化不大時,保存在 alpha 和 beta 節(jié)點中的狀態(tài)不需要太多變化,避免了大量的重復(fù)計算,提高了匹配效率。
c. 從 Rete 網(wǎng)絡(luò)可以看出,Rete 匹配速度與規(guī)則數(shù)目無直接關(guān)系,這是因為事實只有滿足本節(jié)點才會繼續(xù)向下沿網(wǎng)絡(luò)傳遞。
5.2 Rete算法的缺點
Rete算法使用了存儲區(qū)存儲已計算的中間結(jié)果,以空間換取時間,從而加快系統(tǒng)的速度。然而存儲區(qū)根據(jù)規(guī)則的條件與事實的數(shù)目成指數(shù)級增長,極端情況下會耗盡系統(tǒng)資源。
a. 容易變化的規(guī)則盡量置后匹配,可以減少規(guī)則的變化帶來規(guī)則庫的變化。
b. 約束性較為通用或較強的模式盡量置前匹配,可以避免不必要的匹配。
六、規(guī)則引擎調(diào)研
規(guī)則引擎有三個概念需要理解,如下:
事實(Fact): 對象之間及對象屬性之間的關(guān)系
規(guī)則(rule): 是由條件和結(jié)論構(gòu)成的推理語句,一般表示為if...Then。一個規(guī)則的if部分稱為LHS,then部分稱為RHS。
模式(module): 就是指IF語句的條件。這里IF條件可能是有幾個更小的條件組成的大條件。模式就是指的不能在繼續(xù)分割下去的最小的原子條件。
根據(jù)業(yè)務(wù)人員編寫的規(guī)則庫和工作內(nèi)存空間當(dāng)前的狀態(tài),通過規(guī)則引擎匹配模式,把滿足的規(guī)則放入議程表,將不滿足的規(guī)則從議程表中刪除。
a、將初始數(shù)據(jù)(fact)輸入至工作內(nèi)存(Working Memory)。
b、使用Pattern Matcher將規(guī)則庫(Rules repository)的規(guī)則(rule)和數(shù)據(jù)(fact)比較。
c、如果執(zhí)行規(guī)則存在沖突(conflict),即同時激活了多個規(guī)則,將沖突的規(guī)則放入沖突集合。
d、解決沖突,將激活的規(guī)則按順序放入Agenda。
e、執(zhí)行Agenda中的規(guī)則。
f、重復(fù)步驟b至e,直到執(zhí)行完畢Agenda中的所有規(guī)則。
6.1 規(guī)則引擎的核心問題
任何一個規(guī)則引擎都需要很好地解決規(guī)則的推理機制和規(guī)則條件匹配的效率問題。
a、規(guī)則引擎將邏輯與數(shù)據(jù)分離
b、數(shù)據(jù)在域?qū)ο笾?,邏輯在?guī)則中。這從根本上打破了數(shù)據(jù)和邏輯的耦合,這可能是優(yōu)點,也有可能是缺點。
但是解耦邏輯可以更容易維護(hù)??梢詫⑦壿嬋拷M織在一個或多個非常不同的規(guī)則文件中,而不是將邏輯分布在許多域?qū)ο蠡蚩刂破?/strong>中。
6.2 外部規(guī)則引擎框架調(diào)研
Java規(guī)則引擎主要有URule (pro) /Drools/easyRule/
介紹 | 優(yōu)點 | 缺點 | 活躍性 | 綜合評估 | |||
---|---|---|---|---|---|---|---|
通過界面配置的成熟規(guī)則引擎: | URule | 純Java規(guī)則引擎(RETE算法)為基礎(chǔ)規(guī) | 則定義方式:提供了向?qū)揭?guī)則集、腳本式規(guī)則集、決策表、交叉決策表(PRO版提供)、決策樹、評分卡決策流配合基于WEB的設(shè)計器,可快速實現(xiàn)規(guī)則的定義、維護(hù)與發(fā)布。 | 商用軟件 | 高 | 五星 | https://github.com/youseries/urule |
Drools | 決業(yè)務(wù)代碼和業(yè)務(wù)規(guī)則分離;適用于大型應(yīng)用系統(tǒng) | 性能高 可整合 可維護(hù) | 學(xué)習(xí)成本高 | 文檔全 持續(xù)更新 流行 | 五星 | https://www.drools.org/ | |
基于java代碼的規(guī)則引擎 | Easy Rules | 一個比較簡單的開源的規(guī)則引擎,使用簡單的Java注解方式或者Java代碼編程方式或者使用表達(dá)式語言或者用規(guī)則描述算子定義規(guī)則,然后使用非常簡單的Java代碼加載事實,規(guī)則,然后就可以在已知的事實上實現(xiàn)具體的行為了。 | 簡單易用一個非常輕量級的框架定義規(guī)則的方式豐富多樣基于POJO,支持復(fù)合規(guī)則 | Github維護(hù)者少 | 四星 | https://github.com/j-easy/easy-rules/releases/tag/easy-rules-4.1.0 | |
基于JVM腳本語言: | Aviator | 各種表達(dá)式的動態(tài)求值 two pass 編譯,最終生成 JVM 字節(jié)碼保證性能比一般解釋型腳本快 | 高性能;輕量級;支持多種類型 | Github維護(hù)者少 | 資料齊,例子多 | 四星 | https://code.google.com/archive/p/aviator/downloads |
MVEL | 使用表達(dá)式語言定義規(guī)則 | 靈活,性能高,無類型限制 | 資料少 | Github更新少 | 三星 | ||
RuleEngine | 一個可以使用SQL腳本來定義規(guī)則的中間件,如下的地址是github上基于RuleEngine的一個web可視化配置項目。 | https://github.com/rule-engine/rule-engine/releases/tag/v1.0-beta.1 |
七、規(guī)則引擎代碼演示
coding地址: git@coding.jd.com:zhangjiangtao1/demo.git
八、規(guī)則引擎調(diào)研總結(jié)
規(guī)則引擎不是銀彈,規(guī)則引擎只是把業(yè)務(wù)規(guī)則從應(yīng)用程序代碼中分離出來,通過配置文件獨立管理,本質(zhì)上就是把原來的Java代碼轉(zhuǎn)化成腳本來動態(tài)解析執(zhí)行而已,還是需要寫代碼
解耦后雖然可以在一定程度上支持快速調(diào)整業(yè)務(wù)規(guī)則,但是由于為了實現(xiàn)通用性,避免與業(yè)務(wù)場景強關(guān)聯(lián),所以規(guī)則引擎都是以DSL(Domain Specific Language))或獨立web頁面進(jìn)行維護(hù),對開發(fā)人員和業(yè)務(wù)人員都具備一定的學(xué)習(xí)成本,而且調(diào)整也會比較繁瑣,很多時候即使培訓(xùn)了業(yè)務(wù)人員也不懂。
綜上:
a、如果只追求無需硬編碼,并且配置人員懂得簡單編碼可以使用通用的規(guī)則引擎,引入規(guī)則引擎可以簡化編碼,而且讓邏輯易于維護(hù);
b、如果還要追求配置界面的可讀性,配置人員無需了解代碼,開發(fā)人員就必須往前走一步,做每個業(yè)務(wù)類型的配置界面,然后再做一個界面到規(guī)則DSL語句的轉(zhuǎn)化功能?;蛘哳愋蚒Rule這樣做一個通用的配置界面,但是通用界面也代表了犧牲可交互性。
九、部分內(nèi)容借鑒文檔:
部分內(nèi)容借鑒于:
a、規(guī)則引擎rete算法介紹 https://www.pudn.com/news/630367772d4eb809bf75ab38.html
b、urule介紹:https://juejin.cn/post/6844903588725178376
c、規(guī)則引擎閑談:https://blog.csdn.net/erik_tse/article/details/119323719
d、規(guī)則引擎閑談:https://blog.csdn.net/erik_tse/article/details/119323719
e、AviatorScript 編程指南(5.0)https://www.yuque.com/boyan-avfmj/aviatorscript/cpow90
作者:京東保險 張江濤文章來源:http://www.zghlxwxcb.cn/news/detail-491656.html
來源:京東云開發(fā)者社區(qū)文章來源地址http://www.zghlxwxcb.cn/news/detail-491656.html
到了這里,關(guān)于規(guī)則引擎調(diào)研及初步使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!