Drools规则引擎介绍及实践
1.規則引擎
規則引擎是由推理引擎發展而來,是一種嵌入在應用程序中的組件,實現了將業務決策從應用程序代碼中分離出來,并使用預定義的語義模塊編寫業務決策。接受數據輸入,解釋業務規則,并根據業務規則做出業務決策。開源的代表是Drools,商業的代表是Visual Rules ,I Log
復雜企業級項目運營及維護過程中隨外部條件不斷變化的業務規則(business logic),
迫切需要分離商業決策者的商業決策邏輯和應用開發者的技術決策,
并把這些商業決策放在中心數據庫或其他統一的地方,讓它們能獨立運行;可以動態地管理和修改規則模板從而提供軟件系統的柔性和適應性
2.Drools規則引擎
Drools具有一個易于訪問企業策略、易于調整以及易于管理的開源業務規則引擎,符合業內標準,速度快、效率高。業務分析師或審核人員可以利用它輕松查看業務規則,從而檢驗是否已編碼的規則執行了所需的業務規則。
Drools是為Java量身定制的基于Charles Forgy的RETE算法的規則引擎的實現。支持Java代碼直接嵌入到規則文件中,使得商業規則有了更自然的表達。
Drools主要分為兩個部分:一是Drools規則,二是Drools規則的解釋執行。規則的編譯與運行要通過Drools 提供的相關API 來實現。而這些API 總體上游可分為三類:規則編譯、規則收集和規則的執行
3.Drools規則引擎優點
3.1申明式編程
明確規則機制讓我們可以“做什么”
規則機制的核心優勢在于可以簡化對于復雜問題的邏輯表述,并對這些邏輯進行驗證。
規則機制提供一個如何解決問題的說明,并說明每個決策的是如何得出的
3.2業務邏輯和數據分離
業務數據存儲業務對象中,業務決策存儲規則中,獨立運行
3.3速度和可擴展性
使用網絡算法(Rete algorithm),跳躍算法(Leaps algorithm),提供了非常高效的方式根據業務對象的數據匹配規則
3.3.1 Rete算法
Rete算法是一個快速的模式匹配算法,它通過存儲關于規則的信息而獲得速度
Rete算法的基本思想是保存過去匹配過程中留下的全部信息,以空間代價來換取執行效率 。對每一個模式 ,附加一個匹配元素表來記錄WorkingMemory中所有能與之匹配的元素。當一個新元素加入到WorkingMemory時, 找出所有能與之匹配的模式, 并將該元素加入到匹配元素表中; 當一個無素從WorkingMemory中刪除時,同樣找出所有與該元素匹配的模式,并將元素從匹配元素表中刪除。 Rete算法接受對工作存儲器的修改操作描述 ,產生一個修改沖突集的動作
Rete的高效率主要來自兩個重要的假設
時間冗余性:facts在推理過程中的變化是緩慢的, 即在每個執行周期中,只有少數的facts發生變化,因此影響到的規則也只占很小的比例。所以可以只考慮每個執行周期中已經匹配的facts.
結構相似性:許多規則常常包含類似的模式和模式組。
?
Rete算法的步驟如下:
1.將初始數據(fact)輸入Working Memory。
2.使用Pattern Matcher比較規則(rule)和數據(fact)。
3.如果執行規則存在沖突(conflict),即同時激活了多個規則,將沖突的規則放入沖突集合。
4.解決沖突,將激活的規則按順序放入Agenda。
5.使用規則引擎執行Agenda中的規則。
重復步驟2至5,直到執行完畢所有Agenda中的規則
3.3.2 Leaps 算法
前向推理引擎,包括LEAPS,都包括了匹配-選擇-執行(match-select-action)循環。即,確定可以匹配的規則,選擇某個匹配 的元 組,此元組相應的規則動作被執行。重復這一過程,直到某一狀態(如沒有更多的規則動作)。RETE和TREAT匹配算法速度慢的原因是,它們把滿足規則條 件的元組都實例化。Leaps算法的最大的改進就是使用一種"lazy"的方法來評估條件(conditions),即僅當必要時才進行元組的實例化。這一改進極大的減少了前向推理引擎的時空復雜度,極大提高了規則執行速度。
Leaps算法將所有的 asserted 的 facts ,按照其被 asserted 在 Working Memory 中的順序( FIFO ),放在主堆棧中。它一個個的檢查 facts ,通過迭代匹配 data type 的 facts 集合來找出每一個相關規則的匹配。當一個匹配的數據被發現時,系統記住此時的迭代位置以備待會的繼續迭代,并且激發規則結果( consequence )。當結果( consequence )執行完成以后,系統就會繼續處理處于主堆棧頂部的 fact 。如此反復。
Leaps算法的效率可以比Rete算法和Tread算法快幾個數量級
3.4規則集中化
通過使用規則,可以創建出一個可運行的知識庫。這就意味著對于業務規則可以具備良好的可閱讀性,可以起到文檔的作用
3.5易懂的規則
通過模型對象以及模型說明語言(Domain Specific Languages)能讓你使用很接近自然語言的方式為領域問題建模。借助于這些方式,可讓非技術領域的業務使用來描述業務問題
4.Drools規則模板
| package rules; ???????????????????????????????????????????????// 規則包名路徑 |
4.1無約束匹配模式
???rule "1002"
????when
????????ProductManageVo()
????then
????????System.out.println("無約束的匹配模式,匹配ProductManageVo對象即可");
????end
4.2有條件匹配模式
rule "1003"
????when
????????ProductManageVo(topPrice>0)
????then
????????System.out.println("有條件匹配模式,ProductManageVo.topPrice>0即可");
????end
4.3匹配并綁定屬性模式
rule "1004"
????when
????????event:ProductManageVo($topPrice : topPrice>0)
????then
????????System.out.println("有條件匹配模式,ProductManageVo.topPrice>0;" +"并賦值屬性:"
+event.getBarcode()+",$topPrice="+$topPrice);
????end
5.Drools支持的條件約束
rule "1005"
????when
????????ProductManageVo(thirdPrice!=null&&topPrice>0)
????then
????????System.out.println("條件約束表達式");
????end
| 約束 | 描述 |
| !. | 使用此運算符可以以空安全的方式取消引用屬性。!.運算符左側的值不能為null(解釋為!= null) |
| [] | 按List索引訪問值或Map按鍵訪問值 |
| <,<=,>,>= | 在具有自然順序的屬性上使用這些運算符 |
| ==, != | 在約束中使用這些運算符作為equals()和!equals()方法 |
| &&,|| | 組合關系條件 |
| matches,not matches | 使用這些運算符可以指示字段與指定的Java正則表達式匹配或不匹配 |
| contains,not contains | 使用這些運算符可以驗證Array或字段是否包含或不包含指定值 |
| memberOf,not memberOf | 使用這些運算符可以驗證字段是否為定義為變量Array的成員 |
| soundslike | 使用英語發音來驗證單詞是否具有與給定值幾乎相同的聲音(類似于該matches運算符) |
| in,notin | 使用這些運算符可以指定一個以上的可能值來匹配約束(復合值限制) |
6.Drools集合應用
6.1從集合中取數據
rule "1006"
????when
????????$event:ProductManageVo()
????????$backList : BackList(type==0) from?$event.backLists
????then
???????System.out.println("遍歷集合數據:"+$backList);
????end
?
7.SpringBoot引入Drools.jar
| <dependency> |
8.Java Demo
RiskConfig表結構
CREATE TABLE `r_risk_config` (
? `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
? `risk_code` varchar(128) NOT NULL COMMENT '規則編碼',
? `risk_name` varchar(256) DEFAULT NULL COMMENT '規則名稱',
? `risk_content` text COMMENT '規則模板',
? `risk_key` varchar(64) DEFAULT NULL COMMENT '規則模板md5,驗證是否需要重新加載',
? `risk_type` tinyint(3) DEFAULT '0' COMMENT '0-商品,1-訂單',
? `risk_level` tinyint(3) DEFAULT '0' COMMENT '風控等級',
? `is_send_email` tinyint(3) DEFAULT '0' COMMENT '是否發送郵件0-否,1-是',
? `is_wx_news` tinyint(3) DEFAULT '1' COMMENT '是否發送告警信息0-否,1-是',
? `is_fuse` tinyint(3) DEFAULT '0' COMMENT '是否熔斷流程0-否,1-是',
? `is_black_list` tinyint(3) DEFAULT '0' COMMENT '是否添加黑名單0-否,1-是',
? `status` tinyint(3) NOT NULL DEFAULT '1' COMMENT '是否生效0-否,1-是',
? `create_time` datetime DEFAULT NULL COMMENT '創建時間',
? `creator` bigint(20) DEFAULT NULL COMMENT '創建人',
? `modifier` bigint(20) DEFAULT NULL COMMENT '修改人',
? `modify_time` datetime DEFAULT NULL COMMENT '修改時間',
? `dr` tinyint(1) DEFAULT '0' COMMENT '刪除標志',
? `ver` int(11) DEFAULT '1' COMMENT '版本號',
? `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '時間戳',
? PRIMARY KEY (`id`),
? UNIQUE KEY `uni_risk_code` (`risk_code`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='風控規則表';
規則模板RiskConfig配置
?
| @Service |
總結
以上是生活随笔為你收集整理的Drools规则引擎介绍及实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 世界领先的界面设计公司:The Skin
- 下一篇: 大家放松下,仿《大腕》经典对白