舊文回頭來看,有不少地方比較模糊,惋惜我如今找不到jess的源代碼了,不然能夠好好再看看實現細節,先搬過來再說,之後在研究啦,做爲入門湊合着看吧。node
Rete算法是Charles Forgy在1979年的論文中首次提出的,針對基於規則知識表現的模式匹配算法。目前來講,大部分規則引擎仍是基於rete算法做爲核心,但都有所改進,好比drool,jess等等,下面介紹rete算法的概念,一些術語,以及使用規則引擎須要注意的問題。算法
先來看看以下的表達式:服務器
(name-of-this-production
LHS /* one or more conditions */
-->
RHS /* one or more actions */
)網絡
name-of-this-production就是規則,LHS(left hand side)一系列條件,RHS(right hand side)這個是咱們知足條件後應該執行的動做。數據結構
結合該圖介紹幾個概念:ide
production memory(PM)是由全部的production造成。性能
working memory(WM)由外界輸入根據匹配算法造成的,反映了運行中的規則引擎的狀態,記錄各類數據, WM中每個item稱爲working memory element(WME) ,由外界的輸入產生。測試
agenda負責匹配,衝突解決,執行動做。優化
rete是網絡的意思(拉丁語),它將全部的規則最終解釋(或編譯)生成一個識別網絡,其中包括了alpha網絡,beta網絡。alpha網絡是根據LHS生成的網絡,它根據外界的輸入快速識別是否存在condition成立,而且跟其beta網絡交互更新整個網絡的狀態,以下圖:this
最基本的alpha網絡就如上圖所示,相似於這樣,全部的condition被parse到這樣的網絡,當外界輸入wme時,該wme會進入這樣一個網絡進行辨識,若是到達最底端,證實一個condition成立了,固然,如圖這個網絡算是最簡單的實現了,實際規則引擎須要提供更快速的算法去辨識輸入的wme,好比將圖中color的各類值存入hashtable,或者是jumptable,又或者是trie tree。整個alpha network是一個巨大的字符串匹配和過濾網絡,須要將各類數據結構組合在一塊兒去實現海量condition狀況下的快速匹配。各類規則引擎的實現又是不一致的,好比jess,以下圖:
(defrule done
(TESTING)
(number ?number)
(TEST IS DONE)
(INIT CREDIT 5)
(CUSTOMER AGE ?age)
(has ?type "PP"))
=>
(assert (TEST COMPLETED)))
這個production的解釋後生成的網絡,這裏咱們先注意紅色的節點,這些節點就是alpha網絡的節點,這個圖只是描述了大體的過程,以第一列爲例,第一個紅色node表示輸入是否匹配TESTING這個字符串,第二個node匹配在TESTING後面的參數數量(slot)是否匹配0,若是咱們assert TESTING進入WM,那麼這個fact是能夠匹配到done這個rule的第一個condition的,其餘能夠依次類推,值得注意的是最後一個condition,has是咱們自定義的function,相似這樣的function,jess沒有單獨生成一列,只是將它做爲CUSTOMER AGE ?age這一列的最後一個node,這樣的condition有個特色就是須要執行一段代碼去判斷某個事實是否成立(不只僅只是作字符串的操做),這段代碼不只僅是字符串的匹配,同時還具備實時性,相似這樣的condition開發中須要注意,由於alpha network在運行期會不止一次去執行這個condition是否成立,這個是匹配算法的特性決定,因此,咱們須要用cache或者規則語言的特性去避免沒必要要的執行code以提升性能。
下面貼個比較複雜的例子:
圖太大,一個截不下來。。。。。。
下面咱們結合兩個例子說說beta網絡,當alpha網絡過濾後condition成立,WME被傳遞到beta網絡時,綠色的node就要發揮做用了,這個node就是join node,它有兩個input,一個join node ,一個alpha node(紅色),join node是由多個WME組成的,對於初始的join node 咱們稱爲left input adapter 如圖中×××的node,該node是空的,那麼第一個把這個node做爲left input的join node就只包含了一個WME,下一個join node則包含了兩個WME,以此類推。圖中天藍色的node上方的join node 徹底匹配了production執行須要的condition,因此這個rule就被激活等待執行了。
假設咱們須要編輯業務邏輯,那麼最好的描述載體就是流程圖,簡單的流程圖包含如下一些基本單元:起始節點,邏輯判斷,執行動做,結束節點。這些節點能夠完成最簡單的業務邏輯描述,那麼咱們把這些流程parse到規則的時候,咱們會怎麼去作,第一個邏輯判斷單元返回true,因而咱們執行某個動做,第二,三個邏輯判斷單元返回true咱們執行某個動做,至關於會parse到兩個規則,符合condition1,production1觸發,符合condition2,3,production2觸發,有了beta網絡,咱們在觸發production2時只須要判斷condition2,3是否成立,對於更復雜的狀況,beta網絡提升了速度,避免了重複匹配。
開發中使用規則引擎也遇到些問題,總結以下:
1)規則引擎中對於特殊condition的處理,因爲condition會在部分production中重複出現,因此會形成condition的重複匹配問題,影響了程序的性能,這個要結合項目去優化rule腳本的parse或者使用cache去提高性能。補充:能夠將動態執行的condition放到LHS的最後,保證只有在必要的時候纔會執行,固然具體狀況還得看具體rule engine的實現啦
2)內存消耗問題,rete算法是空間換時間,因此對於內存的消耗是比較大的,特別是加載rule的時候(生成網絡),在運行期內存會緩慢增加,因此gc效率須要注意,同時單個服務器所能承受的壓力(多個WM)也跟規則引擎息息相關。
3)測試,對於使用規則去表達業務的系統,如何測試是必須解決的問題,對於這個問題,也只能保證基本的流程分支覆蓋測試,對於複雜狀況下的defect很難發現,不過有些原則須要注意,若是要使用規則引擎,咱們必須徹底以規則引擎爲核心,對於業務邏輯必須儘量的抽取到規則引擎去實現,對於擴展實現的function粒度必須小且簡單,不要再代碼中去實現業務邏輯。
4)大部分的condition須要是不變的,也就是說基本信息須要保持穩定不變。好比某客戶公司上屬集團信用額度大於100w這樣的condition,這個額度變化的頻度不會很高,不須要去實時匹配。
5)remove WME production是較複雜的操做,規則較複雜時,應該儘可能少去作這樣的操做。