簡介:本文介紹了智能交通系統中的一個典型業務場景,並展現了如何通過 Drools BRMS 實現該業務 規則的動態管理。
引言
業務規則管理系統(BRMS)在電信,銀行和政府等各行業中廣泛使用,用來支持業務規則的編輯,管 理和部署,以適應業務的快速變化。Drools 是一款基於 Java 的開源產品,包括業務規則執行引擎和業 務規則管理系統。本文首先介紹了業務規則引擎和業務規則管理系統的基本概念和體系結構,然後介紹一 個智能交通系統中的典型業務場景,最後展現如何通過使用 Drools BRMS 來實現這個業務場景,並根據 不同的業務需要靈活配置這些業務規則。
基本概念介紹
智能交通系統中的業務規則簡介
智能交通系統中的道路收費系統的基本業務場景是:載有特定裝置(通常是電子標簽裝置或者是有全 球衛星定位功能的裝置)的車輛進入收費區後,收費區的信號探測器發出掃描信號,檢測並獲取該車的有 關信息,譬如信號探測系統能夠獲取並記錄諸如車輛的幾何尺寸、車重、車型等數據。對於沒有安裝這種 裝置的車輛來說,系統可以通過攝像機拍攝記錄獲得車型、車牌號等信息。然後根據不同的收費業務規則 ,針對不同的車輛采取不同的收費標准。
目前主要的道路收費業務規則有基於特殊道路使用收費、基於區域收費和基於距離 / 時間收費等。
基於特殊道路使用收費:這種收費模式通常是針對特殊的道路,如某條高速公路。這種收費的業務規 則比較簡單,當車輛通過一次收費檢測點就收取一次費用。基於特殊道路的使用收費模式還廣泛應用在城 市擁堵費收取中。當車輛通過某條比較擁堵的公路時,就會被收取相應的費用。
基於區域收費:這種收費模式是指在某個指定的區域內對行駛車輛收取一定的費用。需要記錄車輛何 時何地進入指定區域以及何時何地離開,當獲得完整的車輛進入和離開的信息以後,將會產生一次計費。
基於距離 / 時間收費:這種收費模式通常應用在整個國家的公路網,可以覆蓋所有的車輛類型,收費 的業務規則是以車輛行駛的距離(時間)為輸入。首先在車輛上安裝一個特殊的車載器件(目前運用很多 的是有全球衛星定位功能的儀器),當裝有 GPS 儀器的車輛在開上高速公路後,收費系統借助於衛星信 號和其他定位傳感器,得到車輛的位置,通過衛星定位系統確定車輛在高速公路上行駛的裡程,然後進行 結算,自動統計繳費額,並把數據按一定間隔時間發送到道路收費中心,由收費中心向擁有車輛的運輸公 司開出賬單,收取這段裡程的道路使用費用。
業務規則引擎(Rule Engine)
前面提到的智能交通系統中的業務規則,是業務場景中真實存在的,為了實現這些業務規則,我們可 以通過在程序代碼裡,用各種編程語言和其他業務邏輯同樣的實現。但是由於業務規則的易變性,很容易 導致程序代碼的重寫,無疑會增加維護的成本和無法快速反應需求的變化。業務規則引擎提供了對業務規 則解析執行。降低實現業務邏輯的復雜性,提高了應用程序的可維護性和可擴展性。
業務規則管理系統 (BRMS)
業務規則管理系統是在業務規則引擎基礎上的擴展,提供了一套包含業務規則整個生命周期的管理系 統。減輕了業務規則維護的工作量。降低了復雜性,方便用戶而不是技術專家來管理業務規則。提供了業 務規則動態修改的能力,即業務人員通過在系統中改變業務規則文件,應用程序無需重新裝載,就能及時 反應規則的變化。
Drools BRMS 4.0.7 簡介
Drools BRMS 是一個 Web 應用程序,可以部署在大部分的支持 J2SE 1.5 的 Web 容器下,如 Tomcat 5.5。Drools BRMS 是從 Drools 的 4.0 版本之後加入的,我們使用的版本是 4.0.7。
Drools BRMS 架構體系分為三大部分,第一部分是 UI 層,提供了一個基於 Ajax 技術的業務規則編 輯、管理工具。利用 Google Widget Toolkit(GWT)實現 Ajax 技術,提供了較好的用戶體驗。第二部 分是規則文件倉庫層,將規則文件統一保持在文件系統或關系數據庫。基於開源 Apache 工具的 JackRabbit 實現。JackRabbit 是一種支持結構化和非結構化數據的內容存儲,是 Java 內容倉庫規范 JCR 的一個實現。最後一個是 Drools 的核心引擎,用來對用戶提交的規則文件進行驗證、編譯和部署。
開發人員通過規則文件的編輯部署,生成了包含 rule 的 package 對象,這是引擎可直接操作的內存 對象。BRMS 通過一個 URL 提供對這個對象的 HTTP 訪問。第三方可以通過 RuleAgent 的 API 來訪問這 個 URL,程序自動下載這個 Package 對象就直接可以在規則引擎運行,得到規則執行的結果。整個結構 如下圖所示
圖 1. Drools BRMS 組件
詳細業務規則抽取
這裡以一個高速公路收費的場景為例,抽取其中詳細的計費業務規則。此業務規則是前面介紹過的基 於特殊道路使用的收費模式的一種應用,當車輛通過一次收費檢測點就收取一次費用,產生一條收費賬單 。對於不同的車輛,通過不同的道路,將會被收取不同的費用。
業務規則輸入
不同的道路類型、收費檢測點類型、車輛類型、賬戶類型、車輛使用類別和不同的通行時間會產生不 同的費用。這些信息都將作為計費業務規則的輸入。
道路運營商代碼
收費檢測點代碼
車輛通過收費檢測點時間
車輛類型 ( 摩托車、小型轎車、卡車等 )
車輛用途類別
車輛識別方法 ( 通過電子標簽識別、通過車牌攝像識別等 )
車輛綁定賬戶類別
業務規則輸出
收費項目列表 ( 如道路基本使用費、附加費和折扣等 )
收費項目明細 ( 包括收費類別以及費用金額 )
業務規則抽取結果
道路使用費的業務規則
如果車輛安裝合法的電子標簽設備,當車輛通過收費站時,系統將通過讀取電子標簽的內容識別車輛 信息。如果車輛未安裝合法的電子標簽設備,系統會啟動攝像頭拍攝車輛通過時的圖片,自動識別圖片中 的車牌信息。如果系統無法自動識別,將通過人工識別獲得車輛信息。無論是通過電子標簽識別,自動車 牌識別,還是人工識別,當獲得車輛本身信息以及車輛綁定的賬戶信息之後,可以根據相應的業務規則計 算出道路使用費用。
一個簡單的道路使用計費規則如下表所示:
序號 道路運營商代碼 收費檢測點代碼 車輛綁定賬戶類別 車輛類型 日期 時間 車輛用途類別 道路基本使用費 1 2 01 001 ANNUAL 1 2,7 8,24 A 5.1 2 2 01 001 ANNUAL 1 2,7 0,8 A 4.9 3 2 01 001 ANNUAL 1 1,1 8,24 A 5 4 2 01 001 ANNUAL 1 1,1 0,8 A 3.3 5 2 01 001 ANNUAL 2 2,7 8,24 B 6.5 6 2 01 001 ANNUAL 2 2,7 0,8 B 5.3 7 2 01 001 ANNUAL 2 1,1 8,24 B 5.4 8 2 01 001 ANNUAL 2 1,1 0,8 B 3.7 9 2 01 001 TEMP 3 2,7 8,24 C 5.2 10 2 01 001 TEMP 3 2,7 0,8 C 3.4
附加費用的業務規則
在 3.3.1 中,我們提到,系統可能會通過不同的方法識別車輛:電子標簽識別(TAG),自動識別車 牌(OCR)或人工識別車牌 (MIR),不同的識別方法可能產生不同的附加費用。電子標簽識別快速、簡單 ,這裡附加費用為 0。自動車牌識別將啟用光學圖片識別引擎來識別車牌,產生一定的附加費(0.5 元) 。而人工識別則是在自動車牌識別失敗後,通過人眼辨別圖像識別車輛,需要耗費更多的系統資源和人力 ,產生了較高的附加費用(1 元)。附加費用的收取可以鼓勵車主使用電子標簽,使得收費更快捷簡單。
序號 車輛識別方法 附加費 1 TAG 0 2 OCR 0.5 3 MIR 1
折扣的業務規則
用戶在為車輛注冊綁定賬戶時,可以選擇不同的賬戶類型,如臨時賬戶 (TEMP)、年結算賬戶(ANNUAL ),不同的賬戶類型可以給予不同的優惠。
序號 車輛綁定賬戶類別 折扣 1 ANNUAL -0.2 2 TEMP -0.4
應用開發
基於上面的介紹,我們了解了一個典型的業務場景。下面我們介紹如何用 Drools 實現這個業務場景 。我們首先要建立一個完整的規則庫,包括在 Drools BRMS 上建立工作目錄,業務對象建模以及基於決 策表的規則文件編寫。其次我們編輯了一個簡單的用戶界面來調用規則引擎。最後我們介紹對規則進行的 修改能夠在我們的用戶界面上及時展現。
建立工作目錄(Package)
工作目錄是存放業務規則文件,業務對象以及其他一些規則相關對象的地方。將 Drools BRMS 安裝到 Tomcat 並啟動後,打開 URL:http://localhost:8080/drools- jbrms/org.drools.brms.JBRMS/JBRMS.html,點擊 Login 進入系統,我們就可以看到系統的主界面。
Drools BRMS 以包的方式管理所有相關的規則文件,函數和業務對象模型等。我們點擊“create new package”的圖標,創建一個名為 com.sample.rule 的工作目錄。以後我們將在這個包下創建規則和業務 對象模型。
圖 2. Drools 的主界面
業務對象建模
BOM(Business Object Model) 是業務規則引擎所要操作的對象。在 Drools 中業務對象就是普通的 Java 對象。我們建立一個叫做 RuleInput 的對象如圖 3 所示,這是一個保存輸入輸出參數的對象。包 含 identifyMethod,detectionTime,detectionPointCode,accountType,vehicleClass,dayOfWeek, timeOfDay,operator,purposeOfUse,這些都是作為判斷條件的參數,而 TollFee,AdminFee 和 Discount 對應三種計算所得的子項,存放通行費,附加費和折扣值。
圖 3. 業務對象 RuleInput
在 com.sample.rule 包下創建一個叫做 RuleModel 的模型歸檔文件。將前面的 Java 文件導出成 Jar 包,點擊上傳圖標上傳到 Drools BRMS 中。
圖 4. 上傳業務對象模型
在包的配置中添加類路徑,以便系統裝載這個 RuleInput 類。點擊工作目錄 com.sample.rule,選擇 Edit Page Configuration,如圖 5 在 Header 編輯框裡,添加“import com.sample.rule.RuleInput” ,點擊 save and validate configuration 按鈕來保存配置。這樣就完成了一個業務對象模型。
圖 5. 添加類路徑
基於決策表的規則文件
這一步我們就要進入關鍵的一步了——創建和編輯規則文件。Drools 支持多種業務規則的定義方式, 如基於業務規則語言 drl(Drools Rule Language)的方式,基於自然語言的方式和基於決策表的方式等 。決策表是一種簡單但是精確的表示規則的方式,容易使業務人員理解和使用。所以我們采用基於決策表 來定義我們的業務規則。決策表可以用 MS office 或 OpenOffice 編輯。其中的一行就是一條規則,分 為條件和動作兩部分,如果滿足條件則執行相應的動作。
決策表包括以下幾部分:
規則集合的定義
一個文件對應一個規則集合,可以包含多個規則表。第二行關鍵字 RuleSet,其值和工作目錄名一致 。Import 關鍵字定義規則引擎裝載業務對象的類路徑。Notes 關鍵字是用來注釋這個規則集合的用途。
規則表的定義
每個規則表,分為表格頭和表格體兩部分。表頭定義表格的模板信息。第六行 RuleTable 關鍵字表示 一個規則表從這裡開始。第七行說明所在列是條件還是動作。第八行表示規則所要操作的對象模型,我們 聲明了一個 fee 變量,它的類型是前面定義的 RuleInput 類。在動作那一列我們就可以使用 fee 這個 變量了。第九行就是條件模板或者動作模板,定義了輸入業務模型實例的屬性滿足條件模板就執行動作模 板,例如輸入的 RuleInput 實例如果 operator==201,則滿足了表格體的第一行第一列條件。同樣,如 果車輛被探測到的時間在 8 點到 24 點之間,那麼滿足了表格體的第一行第六列條件。其中 $1 表示第 一個參數,$2 表示第二個參數,當只有一個參數時,就用 $param 來表示。第十行是對各個屬性的描述 。
圖 6. 基於決策表的規則文件——計算通行費
同樣,我們定義了兩個決策表來計算附加費和折扣
圖 7. 基於決策表的規則文件——計算附加費和折扣
通過上面的描述,我們定義了一個完整的規則文件。然後我們就可以上傳到 Drools BRMS 上了。打開 剛才的 URL,首先要創建一個類別,選擇左邊的 Admin 菜單,選擇 Manage Category 頁,創建一個 SampleCtg 類別。
圖 8. 創建類別
然後點擊“create new rule”圖標,創建一個 Business Rule Asset,命名為 SampleRule。類別選 擇剛才的 SampleCtg,選擇規則類型為決策表類型。然後上傳決策表文件。
圖 9. 上傳規則文件
上傳之後,點擊 Validate 按鈕來驗證上傳的規則文件是否正確。如果有錯誤就根據提示進行改正, 再次上傳驗證直到驗證通過。
最後一步就是發布這個業務規則,發布時 Drools BRMS 提供了一個 http 地址,這樣客戶端可以通過 這個地址訪問到這個業務規則。點擊包 com.sample.rule,選擇右邊的 Build, Validate and deploy 欄 目,點擊 Build Package,然後點擊 Create snapshot for deploy 鍵,命名為 TollRule,點擊創建, 這樣就完成了發布。在 Deployment 菜單我們可以看到發布的規則文件地址為 http://localhost:8080/drools-jbrms/org.drools.brms.JBRMS/package/com.sample.rule/TollRule。
圖 10. 發布規則
調用程序
我們開發了一個簡單的 JSP web 客戶端來模擬實際的業務系統,需要調用 Drools BRMS 來顯示規則 執行的結果。Drools 的核心包中提供了一個 RuleAgent 的 API,能夠動態地訪問在 BRMS 上發布的業務 規則文件。RuleAgent 能夠將規則文件下載到本地並裝載到規則引擎進行解析執行。RuleAgent 需要一些 參數進行初始化對象,這些參數保存在一個配置文件中,用單例模式裝載配置文件生成一個唯一的 RuleAgent 對象。從 RuleAgent 得到一個 StatefulSession,就可以執行規則了。在 session 對象中注 入前面定義的一個 RuleInput 對象。fireAllRules() 就執行了所有的規則。得到的結果保存在 RuleInput 的輸出屬性中。
清單 1. 執行規則的關鍵代碼
public class ChargeSessionHelper {
private static RuleAgent agent;
private static StatefulSession session;
public static StatefulSession getSession(){
if(agent==null){
agent=loadRuleAgent();
}
//get ruleBase intance
RuleBase ruleBase=agent.getRuleBase();
//create StatefulSession
session=ruleBase.newStatefulSession();
return session;
}
private static RuleAgent loadRuleAgent() {
//initialize the parameters from the property file,get a RuleAgent instance
return RuleAgent.newRuleAgent("/rules.properties");
}
}
public RuleInput excute(){
//create StatefulSession
StatefulSession session=ChargeSessionHelper.getSession();
//insert an instance of RuleInput
session.insert(input);
//fire all the rules
session.fireAllRules();
//destroy the StatefulSession
session.dispose();
//return the result, stored in the input object
return input;
}
Rules.properties 文件包含基本的配置信息。newInstance 如果設為 false,那麼 RuleAgent 不需 要每次都創建一個 RuleBase,當服務器規則文件更新時,StatefulSession 能夠自動更新。url 是設置 成服務器上已部署的規則文件地址。poll=30 表示 RuleAgent 每隔 30 秒都會輪詢一次 url 規則是否有 更新。Name 表示這個 RuleAgent 的名字,將會出現在日志裡。localCacheDir 表示將服務器上的規則文 件緩存到本地的目錄,這個屬性大大提高性能,當服務器規則發生改變時,本地的緩存文件也會自動更新 。
清單 2. 客戶端連接業務規則管理系統的配置
newInstance=false
url=http://localhost:8080/drools-jbrms/org.drools.brms.JBRMS/
package/com.sample.rule/TollRule
poll=30
name=TollRule
localCacheDir=c:/temp
下圖是我們的一個調用界面
圖 11. 業務系統模擬
規則的動態修改
Drools BRMS 提供了規則動態修改的功能。當業務規則發生變化,如 OCR 附加費從 50 提高到了 80 ,我們只需要將第二張決策表的 50 改成 80,重新上傳這個文件,並且發布這個業務規則。不需要重新 啟動應用,修改後的規則能夠實時地應用到業務系統中,即我們的規則調用頁面刷新後,就能展現附加費 從 50 提高到了 80
總結
Drools BRMS 雖然相比商業化的業務規則管理系統還有一些不足,但卻是目前較好的開源業務規則管 理系統。在基於 Drools 這個強大的開源規則引擎上,提供了一個輕量級的管理系統。基於 Web 2.0 Ajax 技術,提供了較好的用戶友好度,支持規則文件的上傳,編輯,版本管理,編譯部署等整個過程。 實現了業務規則的動態配置。滿足在業務規則頻繁更新的行業中應用。
本文介紹了如何通過業務規則管理軟件 Drools BRMS,實現智能交通系統中的業務規則。為了展示規 則的動態修改,我們開發了一個 Web 客戶端來訪問規則。
本文配套源碼