巫湘林
桂林理工大學信息科學與工程學院 廣西 541004
隨著計算機技術和網絡技術的發(fā)展,軟件也逐漸向分布式,多平臺下應用,而消息中間件為解決這類軟件間通信提供了便捷。消息中間件的發(fā)布/訂閱模式得到了廣泛應用,主要是通過消息代理使消息在提供者與消費者間可以實現靈活的傳遞。JMS(Java message service)是Sun公司提出的一種統一消息中間件系統接口的規(guī)范,給出了消息中間件互相訪問的標準方法,支持同步與異步的兩種通信方式。JMS解決了企業(yè)級軟件開發(fā)過程中的資源分配,組件重用等問題,有效提高了軟件的健壯性。
JMS定義了點對點、發(fā)布/訂閱兩種消息傳遞模式。點對點模式中,每個創(chuàng)建的消息先保留在隊列中,并且發(fā)送者知道惟一的接收者地址,等待恰當的時候才將消息發(fā)送給接收者。在發(fā)布/訂閱模式中,發(fā)布者將消息發(fā)送到一個主題,系統負責將消息發(fā)送給所有對該主題感興趣的訂閱者。其優(yōu)勢是同一時間可能多個訂閱者接收同一個消息,不必多次建立連接,節(jié)省了網絡資源,同時提高了消息傳遞的靈活性。
消息在JMS的整個消息傳遞過程中作為媒介連接著發(fā)送者與接收者。消息包含消息頭,消息屬性和消息體。消息頭包含了消息標識與路由的值;消息體包含了消息的實際內容。消息屬性包含了一些特定的應用程序屬性、JMS定義的屬性和用戶自定義的屬性,通過這些屬性為消息過濾提供了保障。消息消費者通過對消息頭字段和屬性指定感興趣的內容,并以字符串的形式將過濾條件送至消息選擇器,這樣保證了消息消費者只會接受到自己指定的消息。
傳統的消息選擇方式下,訂閱列表中每個消息選擇器都會被JMS提供者進行匹配處理,當滿足條件時才會將這個消息發(fā)送給訂閱者。對于消息發(fā)布與訂閱者數量比較多時會存在許多相同或相似的訂閱條件,傳統的做法并沒有考慮利用這些共同點來提高消息匹配效率。文獻3中提出的算法主要解決了相同屬性而值不同的多個訂閱條件的消息過濾情況。文獻4中提出的算法主要解決了單個訂閱條件下各個屬性間的邏輯關系不同的消息過濾情況。本文將以上兩種算法思想結合得到一種新的消息過濾算法。
首先準備前期工作,對訂閱條件進行部分調整:
(1) 對所有的消息選擇器進行預處理,調整所有邏輯操作符and連接的屬性使之排在選擇器前面。以下是消息選擇器的條件表達式示例:
(a) S1=(BookName =’java basis’) or(NumberOfBuys >50)and (Price<20);
(b) S2=(BookName=’c++ basis’) and (NumberOfBuys>40)or (author =’simth’);
(c) S3=(BookName=’ java basis’) or (NumberOfBuys>40)or (author =’simth’);
第一個消息選擇器的條件表達式調整為:S1=(NumberOf Buys >50) and (Price<20)or (BookName =’java basis’);其它兩個消息選擇器不需要調整。
(2) 將調整好的訂閱條件建立一個訂閱條件列表Subs_list。
(3) 建立一個保存所有訂閱條件的屬性列表Pro_list。并將每個訂閱條件的屬性分解后按邏輯符=,>,<分成三類并按值從小到大的順序存入屬性分類列表。屬性分類列表結構如圖1所示。
圖1 屬性分類列表
(4) 建立一個包含兩個分支的訂閱條件雙向鏈表Double_list,左端表示訂閱條件屬性間的邏輯關系,右端表示一個訂閱條件屬性所在Pro_list中索引位置。其結構如圖2所示。
圖2 訂閱條件雙向鏈表
改進的消息過濾算法如下:
(1) 遍歷訂閱列表,如果訂閱條件在Double_list中不存在,則將該訂閱條件添加到Double_list的鏈表中。
(2) 對于訂閱條件的每一個屬性分支,查找Pro_list,若屬性分支在Pro_list中存在,則將它在pro_list中的索引位置保存在Double_list的右端鏈表中;如果屬性在Pro_list中不存在,將該屬性添加到pro_list中,同時將其索引位置保存在Double_list的右端鏈表中。最后將屬性間的邏輯關系保存在Double_list的左端鏈表中。
(3) 將發(fā)送過來的事件進行解析,依次按照事件包含的各個屬性做出不同的操作:遇到屬性使用“=”運算符時,在屬性分類列表中使用二分查找算法查找與事件相同的那個屬性進行匹配。遇到屬性使用“<”運算符時,在屬性分類列表中使用二分查找算法查找與包含小于該事件屬性值的最大相同屬性P及P左端的屬性進行匹配,遇到屬性使用“>”運算符時,在屬性分類列表中使用二分查找算法查找與包含大于該事件屬性值的最小相同屬性P及P右端的屬性進行匹配。最后將匹配了的屬性存入匹配列表match_subs。
(4) 遍歷Double_list的左端,以下分三種情況:
① 如果訂閱條件邏輯符全部是and,則依次將Double_list右端的屬性索引所指的Pro_list的屬性與match_subs比較,其中出現一個false值,不再考慮其后的屬性索引所指的值,直接標記此訂閱條件匹配值為false,否則置為true。
② 如果訂閱條件邏輯符全部為or,則依次將Double_list右端的屬性索引所指的Pro_list的屬性與match_subs比較,其中出現一個true值,不再考慮其后的屬性索引所指的值,直接標記此訂閱條件匹配值為true,否則置為flase。
③ 如果訂閱條件邏輯符包含and 與or,則依次將Double_list右端的屬性索引所指的Pro_list的屬性與match_subs比較。對于and連接的屬性數量為and的數量加1,如果匹配結果全為true,則標記訂閱條件匹配值為true,否則跳過and連接的屬性,接下來or連接的屬性按b的情況進行判斷。
(5) 將完全匹配的結果保存在訂閱列表中。
JMS傳統的消息過濾算法沒有考慮到每個訂閱條件內部的關系,缺乏消息匹配的靈活性。而改進的消息過濾算法中,每個訂閱條件屬性按邏輯操作符的優(yōu)先順序進行了位置的調整,然后再拆分了訂閱條件的屬性,按照屬性名的不同進行分類,減少了JMS提供者對重復消息匹配次數。但改進后的消息過濾算法要消耗訂閱條件屬性調整、分解時間以及對匹配了的屬性列表查找時間。
在比較傳統的消息過濾算法與改進的消息過濾算法的基礎上可知,在訂閱者數量不多情況下兩種算法的匹配時間差不多。但是對于訂閱者數量多并且有多數訂閱條件相似度很高的情況下,改進后的過濾算法可大大減少重復信息的匹配時間,從而提高對整個系統的消息處理效率。
對傳統的消息過濾機制,不能快速處理大量相同或相似消息,通過運用改進的算法,消息處理效率將大幅度提升,也為運用這種消息處理機制的系統開發(fā)提供了一定的借鑒作用。
[1] Mark Richards, Richard Monson-haefel, David A.Chapppell.JAVA Message Service(閆懷志)譯.北京.電子工業(yè)出版社.2010.
[2] 王偉卿,孫莉.基于Java消息服務的消息中間件的應用研究[J].計算機技術與發(fā)展.2009.
[3] 鄭偉,寇應展,陳財林,徐士超.基于公平謂詞法的JMS消息過濾改進算法[J].軍械工程學院學報.2008.
[4] 張彩云,康亞男,成汝震.基于內容的發(fā)布/訂閱模型中高效的匹配算法[J].河北師范大學學報.2009.