351
技術社區[雲棲]
規則引擎選型及應用
規則引擎由推理引擎發展而來,是一種嵌入在應用程序中的組件,實現了將業務決策從應用程序代碼中分離出來,並使用預定義的語義模塊編寫業務決策。
規則引擎具體執行可以分為接受數據輸入,解釋業務規則,根據業務規則做出業務決策幾個過程。
使用規則引擎可以把複雜、冗餘的業務規則同整個支撐係統分離開,做到架構的可複用移植。
規則引擎的應用
相對於業務係統,規則引擎可以認為是一個獨立於業務係統的模塊,負責一些規則的計算等。
一般來說,規則引擎主要應用在下麵的場景中:
- 風控模型配置,風控是規則引擎
- 用戶積分等配置,如日常操作引起積分變化等
- 簡單的離線計算,各類數據量比較小的統計等
常用規則引擎的選型
目前的規則引擎係統中,使用較多的開源規則引擎是Drools,另外還有商用的規則管理係統BRMS是ILOG JRules。
Drools
Drools是一個基於Java的開源規則引擎,可以將複雜多變的規則從硬編碼中解放出來,以規則腳本的形式存放在文件中,使得規則的變更不需要修正代碼重啟機器就可以立即在線上環境生效。
目前版本是5.0.1,Drools從5.0後分為四個模塊:
- Drools Guvnor (BRMS/BPMS)
- Drools Expert (rule engine)
- Drools Flow (process/workflow)
- Drools Fusion (cep/temporal reasoning)
Ilog JRules
Ilog Jrules是完整的業務規則管理係統(BRMS),它提供了對整個企業業務規則進行建模、編寫、測試、部署和維護所必需的所有工具。
Ilog Jrules主要包括以下4個組件:
- Rule Studio(RS) 麵向開發人員使用的開發環境,用於規則的建模和編寫
- Rule Scenario Manager 規則測試工具
- Rule Team Server(RTS) 基於Web的管理環境,麵向業務人員使用,用於規則發布、管理、存儲
- Rule Execution Server(RES) 麵向運維人員使用,用於規則執行、監控
這兩款規則引擎設計和實現都比較複雜,學習成本高,適用於大型應用係統。
Easy Rules
Easy Rules是我偶然間看到的一個規則引擎實現,相比Drools等企業級規則引擎,Easy Rules的應用非常簡單,學習成本低,容易上手。
下麵重點介紹這款輕量級的規則引擎 Easy Rules。
輕量級規則引擎Easy Rules
Easy Rules官方主頁:https://www.easyrules.org/
Easy Rules提供以下功能:
- 輕量級框架和易於學習的API
- 基於POJO的開發
- 通過高效的抽象來定義業務規則並輕鬆應用它們
- 支持創建複合規則
Easy Rules的應用
Easy rules的工程可以從Github下載,構建需要Maven支持。
$ git clone https://github.com/EasyRules/easyrules.git
$ cd easyrules
$ mvn install
Easy Rules打包後是一個單獨的jar,使用時需要添加相關文件到工程中,或者添加Maven依賴:
<dependency>
<groupId>org.easyrules</groupId>
<artifactId>easyrules-core</artifactId>
<version>2.4.0</version>
</dependency>
配置你的業務規則
大多數業務規則可以表示為以下定義:
- 名稱:一種唯一的規則名稱
- 描述:對規則的簡要描述
- 優先級:相對於其他規則的優先級
- 條件:設置規則執行時需要滿足的條件
- 操作:設置的條件滿足時執行的操作
我們可以通過擴展Easy Rules提供的Rule interface來定義規則,或者通過注解,定義自己的規則類。
下麵是內置的Rule接口:
package org.easyrules.api;
public interface Rule {
/**
* 這個方法定義了規則執行的條件
* @return true if the rule should be applied, false else
*/
boolean evaluate();
/**
* 這個方法定義了規則執行的具體動作
* @throws Exception if an error occurs
*/
void execute() throws Exception;
//Getters and setters for rule name,
//description and priority omitted.
}
創建規則引擎
Easy Rules的引擎實例會維護一個不同規則的注冊空間,每個Engine可以被視為一個單獨的名稱空間。
多條規則將會按照他們的自然順序去執行,也就是默認的優先級。
要創建一個規則引擎和注冊規則,可以使用下麵的靜態方法:
RulesEngineBuilder.aNewEngineBuilder():
RulesEngine rulesEngine = aNewEngineBuilder().build();
rulesEngine.registerRule(myRule);
執行下麵的操作啟動規則執行:
rulesEngine.fireRules();
Easy Rules應用實例
下麵通過一個簡單的Hello World示例來展示Easy Rules的具體應用。
通過注解創建一個具體的規則類:
@Rule(name = "Hello World rule",
description = "Say Hello to duke's friends only")
public class HelloWorldRule {
/**
* The user input which represents the data
* that the rule will operate on.
*/
private String input;
@Condition
public boolean checkInput() {
//The rule should be applied only if
//the user's response is yes (duke friend)
return input.equalsIgnoreCase("yes");
}
@Action
public void sayHelloToDukeFriend() throws Exception {
//When rule conditions are satisfied,
//prints 'Hello duke's friend!' to the console
System.out.println("Hello duke's friend!");
}
public void setInput(String input) {
this.input = input;
}
}
接下來創建一個規則引擎的實例,注冊並且啟動這個規則:
public class Launcher {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Are you a friend of duke?[yes/no]:");
String input = scanner.nextLine();
/**
* Declare the rule
*/
HelloWorldRule helloWorldRule = new HelloWorldRule();
/**
* Set business data to operate on
*/
helloWorldRule.setInput(input.trim());
/**
* Create a rules engine and register the business rule
*/
RulesEngine rulesEngine = aNewRulesEngine().build();
rulesEngine.registerRule(helloWorldRule);
/**
* Fire rules
*/
rulesEngine.fireRules();
}
}
規則啟動後會通過一個簡單的條件判斷(控製台輸入),然後執行接下來的動作(輸出規則信息)。
除了規則引擎基礎的規則執行功能, Easy Rules還支持監聽規則執行情況,為規則執行配置調度器,
集成Spring等功能。
關於規則引擎的選型和簡單應用就介紹到這裏,除了風控等大型的應用係統,一些獨立的小型產品需求中,可以合理應用規則引擎實現業務與規則的分離,降低係統間耦合,上麵介紹的Easy Rules就是一個不錯的選擇。
最後更新:2017-04-27 17:00:38