吳瀟峰
眾多的大型跨國(guó)企業(yè),目前都會(huì)有一些IT策略來防止自身的應(yīng)用系統(tǒng)在互聯(lián)網(wǎng)上遭到黑客的攻擊。本文所涉及的客戶在其企業(yè)內(nèi)部網(wǎng)(信任區(qū)域)與互聯(lián)網(wǎng)(非信任區(qū))之間建立了一個(gè)DMZ(緩沖隔離區(qū))區(qū)域。此外,在緩沖隔離區(qū)與企業(yè)內(nèi)部網(wǎng)之間建立一層防火墻。并且使用IBM MQ產(chǎn)品作為跨越這兩個(gè)網(wǎng)絡(luò)區(qū)域的唯一的、可靠的數(shù)據(jù)傳輸通道。企業(yè)服務(wù)應(yīng)用系統(tǒng)被完全相同地部署在緩沖隔離區(qū)和企業(yè)內(nèi)部網(wǎng)絡(luò)中,并且各自擁有獨(dú)立的后臺(tái)數(shù)據(jù)庫(kù)系統(tǒng)。因此,為了使得這兩個(gè)數(shù)據(jù)庫(kù)中的數(shù)據(jù)同步和一致,必須每隔一段時(shí)間同步一次兩邊的事務(wù)處理。由于在緩沖隔離區(qū)和企業(yè)內(nèi)部網(wǎng)絡(luò)區(qū)之間,同時(shí)還部署著許多其他的應(yīng)用,并使用了相同的數(shù)據(jù)通道;所以用戶同時(shí)還需將每個(gè)數(shù)據(jù)包的大小限定為4MB之內(nèi),以防止瞬時(shí)的大數(shù)據(jù)量導(dǎo)致數(shù)據(jù)通道堵塞。
根據(jù)以上的描述,這里有幾個(gè)問題需要我們?nèi)プ鱿鄳?yīng)的處理:
實(shí)時(shí)的應(yīng)用服務(wù)同步操作,每個(gè)網(wǎng)絡(luò)區(qū)域中的事務(wù)處理都將在另一端重復(fù)發(fā)生。消息數(shù)據(jù)在發(fā)送時(shí)作分包處理,在接收端再作組裝處理。失效恢復(fù)處理。
一個(gè)事務(wù)處理同步的基礎(chǔ)框架模塊,如圖1所示:
圖1 事務(wù)處理同步框架
灰色圖框中的組件組成了通用的事務(wù)處理同步模塊。該模塊對(duì)業(yè)務(wù)層應(yīng)用提供了接口,業(yè)務(wù)層的應(yīng)用服務(wù)只需實(shí)現(xiàn)該接口,并在事務(wù)處理函數(shù)中調(diào)用由事務(wù)同步框架所提供的API,而無(wú)需了解底層的詳細(xì)調(diào)用實(shí)現(xiàn)。該API將串化所有的參數(shù)并將相應(yīng)的服務(wù)調(diào)用信息傳輸?shù)搅硪欢?,并將在另一端同樣的調(diào)用執(zhí)行相應(yīng)的服務(wù)。
相應(yīng)的事務(wù)同步處理具體流程如下:
1.應(yīng)用服務(wù)調(diào)用事務(wù)同步處理模塊提供的接口函數(shù)去觸發(fā)事務(wù)同步服務(wù)。
2.事務(wù)同步接口將串化所有的應(yīng)用服務(wù)中的參數(shù)數(shù)據(jù)及調(diào)用對(duì)象信息,并將根據(jù)預(yù)設(shè)的傳輸包大小限制進(jìn)行分包和裝箱處理(根據(jù)應(yīng)用需求傳輸數(shù)據(jù)包的大小將被限定在4MB以下),并設(shè)置相應(yīng)的組號(hào),一次服務(wù)調(diào)用只會(huì)具有一個(gè)相同的組號(hào),以便于之后數(shù)據(jù)包的拆箱,隨后通過MQ控制器對(duì)串化后的數(shù)據(jù)進(jìn)行傳輸。
3.接收端的MessageBean將對(duì)指定的消息通道不間斷地進(jìn)行監(jiān)聽。
4.當(dāng)接收端收到數(shù)據(jù)后,暫不做處理,將該串化的消息數(shù)據(jù)存入數(shù)據(jù)庫(kù),待同組的數(shù)據(jù)包全部到達(dá)后一并處理。
5.當(dāng)處理到相應(yīng)的數(shù)據(jù)包時(shí),首先將擁有相同組編號(hào)的一組數(shù)據(jù)包從數(shù)據(jù)庫(kù)中取出,并按序拆箱和拼接。
6.在接收端將利用Java的反射機(jī)制來調(diào)用反串化后的相應(yīng)的服務(wù)函數(shù);相當(dāng)于將發(fā)送端調(diào)用過的服務(wù)函數(shù)在對(duì)端相同地調(diào)用一次。如果在接收端調(diào)用成功并且事務(wù)提交沒有異常的話,將從數(shù)據(jù)庫(kù)中移除這一組數(shù)據(jù)包記錄。以表示該次事務(wù)同步已成功完成。
如圖2所示:
圖2 應(yīng)用Spring框架中AOP來實(shí)現(xiàn)事務(wù)同步
對(duì)于事務(wù)同步處理流程的步驟2和步驟4,可以看出,在發(fā)送端的業(yè)務(wù)邏輯層的函數(shù)將會(huì)調(diào)用通用事務(wù)同步模塊提供的接口函數(shù),而在接收端則有事務(wù)同步模塊來調(diào)用相應(yīng)的業(yè)務(wù)邏輯層函數(shù)以達(dá)到事務(wù)同步的目的。使用了 Spring框架中的AOP來實(shí)現(xiàn)事務(wù)同步的調(diào)用。而應(yīng)用服務(wù)本身并不需要顯式地調(diào)用事務(wù)同步接口函數(shù);AOP的代理機(jī)制將會(huì)來執(zhí)行該調(diào)用。
“Spring框架中使用代理的設(shè)計(jì)模式來實(shí)現(xiàn) AOP的功能。為了能對(duì)業(yè)務(wù)代碼調(diào)用順序有更好地控制,我們選用了AroundAdvice的模式。創(chuàng)建TransactionSyncInterceptor并實(shí)現(xiàn) MethodInterceptor接口中的 invoke()函數(shù)”[1]。并在其中截獲到的調(diào)用方法及參數(shù)信息進(jìn)行串化及裝箱處理。在成功執(zhí)行MethodInterceptor.proceed()函數(shù)(即原業(yè)務(wù)服務(wù)方法)之后,系統(tǒng)將調(diào)用 MQ控制器提供的函數(shù)將串化和分組的消息數(shù)據(jù)放入MQ的消息隊(duì)列中。其中部分Java代碼描述如下:
本框架中還應(yīng)用了第三方開源組件 Quartz以實(shí)現(xiàn)可配置的定時(shí)執(zhí)行消息數(shù)據(jù)的拆箱及事務(wù)處理的執(zhí)行。“在Quartz中,當(dāng)調(diào)度器被初始化后,它可以被啟動(dòng),置于一個(gè)待機(jī)狀態(tài)并可以被關(guān)閉。注意,一旦當(dāng)調(diào)度器被關(guān)閉,那么它無(wú)法重新啟動(dòng)直到它被重新初始化以后。觸發(fā)器也不會(huì)被激發(fā)(調(diào)度任務(wù)不會(huì)執(zhí)行)直到調(diào)度器被啟動(dòng)?!盵2]
創(chuàng)建QuartzJobSchedulerServlet類,并將其配置在web server啟動(dòng)的servlet列表中,同web servery一同啟動(dòng)加載。部分Java代碼描述如下:
IBM WebSphere MQ產(chǎn)品能夠提供準(zhǔn)確響應(yīng),超低延遲的并且完全符合JMS規(guī)范的企業(yè)級(jí)消息服務(wù)。
WebSphere MQ使應(yīng)用程序在必要時(shí)通信,同時(shí)從開發(fā)和使用角度保持其獨(dú)立性。WebSphereMQ應(yīng)用(我們姑且稱之為應(yīng)用 A),將需要與之通信的其他應(yīng)用,看作是通過隊(duì)列表示的一組服務(wù)接口。這些其他應(yīng)用的物理實(shí)現(xiàn),可能隨著時(shí)間的推移而發(fā)生變化。
“WebSphere MQ 可以降低應(yīng)用程序、Web服務(wù)或網(wǎng)絡(luò)失敗時(shí)數(shù)據(jù)丟失的風(fēng)險(xiǎn)。它也有助于確保數(shù)據(jù)不被復(fù)制,且作為工作或交易的一個(gè)單元完成。可靠的交付意味著WebSphere MQ 形成了許多關(guān)鍵通信系統(tǒng)的驗(yàn)證主干網(wǎng),并被委托交付業(yè)務(wù)關(guān)鍵型和高位值數(shù)據(jù)。WebSphere MQ 可以根據(jù)應(yīng)用程序和 Web 服務(wù)的需求,同步或異步地交付信息。它經(jīng)過某種配置后,也可以為次關(guān)鍵型數(shù)據(jù)提供較健壯質(zhì)量的服務(wù)?!盵3]
在發(fā)送端,超過限定大小的數(shù)據(jù)信息,將首先被分拆成小于4MB的數(shù)據(jù)包集合,并且每個(gè)數(shù)據(jù)包將具有一個(gè)統(tǒng)一的消息組編號(hào)和一個(gè)獨(dú)立組內(nèi)序列編號(hào)。在分拆后這些數(shù)據(jù)包,將通過MQ消息通道進(jìn)行傳輸。
在接收端,每個(gè)數(shù)據(jù)包都能按這兩組編號(hào),重新合并成一個(gè)完整的數(shù)據(jù)包,然后通過反序列化和Java的反射機(jī)制,重新在接收端執(zhí)行一次相應(yīng)的服務(wù)調(diào)用。
每個(gè)數(shù)據(jù)包的最大容量,是定義在一個(gè)系統(tǒng)配置文件中,可以按照不同的客戶的真實(shí)環(huán)境要求進(jìn)行改變。不過必須保證的是在緩沖隔離區(qū)和企業(yè)內(nèi)部的該配置信息的一致性。
一旦包數(shù)據(jù)信息到達(dá)一端的本地消息隊(duì)列中,數(shù)據(jù)接收處理程序,將首先瀏覽一遍整個(gè)數(shù)據(jù)包,并且將該數(shù)據(jù)包存入數(shù)據(jù)庫(kù),同時(shí)將該包數(shù)據(jù)從本地消息隊(duì)列中刪除。當(dāng)所有同組的包數(shù)據(jù)信息到達(dá)后,進(jìn)行包數(shù)據(jù)的組合與反串化,從而獲得能通過Java反射執(zhí)行的服務(wù)調(diào)用。只有當(dāng)該服務(wù)調(diào)用的執(zhí)行成功后,才會(huì)將這一組的包數(shù)據(jù)信息從數(shù)據(jù)庫(kù)中移除。否則,這些包數(shù)據(jù)信息將一直被保存在數(shù)據(jù)庫(kù)中,并等待下一次的執(zhí)行,如圖3所示:
圖3 包數(shù)據(jù)信息保存于數(shù)據(jù)庫(kù)
失效恢復(fù),在該同步模塊中具有相當(dāng)重要的作用,若要保持兩端數(shù)據(jù)的一致性,必須有類似于數(shù)據(jù)庫(kù)事務(wù)處理備份機(jī)制。因?yàn)樵诔霈F(xiàn)爆發(fā)式大數(shù)據(jù)量或者事務(wù)集中處理的時(shí)候,要確保偶發(fā)性的事務(wù)處理失敗或解/壓包數(shù)據(jù)出現(xiàn)錯(cuò)誤時(shí),系統(tǒng)能將狀態(tài)保持,并能保留完整的日志記錄及將來可重新執(zhí)行的事務(wù)數(shù)據(jù)。
在事務(wù)同步模塊中,使用了包消息的持久機(jī)制,消息數(shù)據(jù)直到被成功拆箱執(zhí)行后才會(huì)被全部刪除。并有一個(gè)出錯(cuò)恢復(fù)程式去監(jiān)控執(zhí)行過程中的錯(cuò)誤,并且自動(dòng)重新嘗試執(zhí)行該出錯(cuò)服務(wù),直到該服務(wù)調(diào)用成功數(shù)據(jù)將被移除;或者超出最大重試次數(shù)后,數(shù)據(jù)被表示成不可執(zhí)行,可有管理員從日志中查獲相應(yīng)出錯(cuò)信息,做出相應(yīng)的調(diào)整后,更改包數(shù)據(jù)的執(zhí)行狀態(tài),等待之后的重新執(zhí)行。該出錯(cuò)恢復(fù)程式是一個(gè)基于時(shí)間觸發(fā)器的組件,所以失效恢復(fù)的執(zhí)行間隔都是可配置的,如圖4所示:
圖4 失效恢復(fù)模組
通過使用AOP的理念實(shí)現(xiàn)該事務(wù)同步框架,我們能夠得到以下具有優(yōu)勢(shì)的功能:
1) 自動(dòng)的失效恢復(fù)
系統(tǒng)能在接收端的執(zhí)行期間,自動(dòng)地恢復(fù)執(zhí)行失敗的服務(wù)調(diào)用。
2) 在服務(wù)調(diào)用級(jí)別的同步
通常的數(shù)據(jù)同步組件都是基于數(shù)據(jù)庫(kù)級(jí)別的同步。但是事實(shí)上,也許有時(shí)系統(tǒng)只是需要同步部分的數(shù)據(jù),那些有特殊服務(wù)所做的數(shù)據(jù)更新的同步。因此用這個(gè)事務(wù)同步框架就可實(shí)現(xiàn)基于服務(wù)級(jí)別的可配置的數(shù)據(jù)同步。并且框架可以與時(shí)下的SOA框架做到無(wú)縫連接整合。
3) 用AOP技術(shù)達(dá)到低耦合
對(duì)業(yè)務(wù)處理過程中的切面進(jìn)行提取,它所面對(duì)的是處理過程中某個(gè)步驟或子階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。文中的事務(wù)處理同步框架正是使用了AOP的設(shè)計(jì)理念,運(yùn)用配置文件來定制服務(wù)級(jí)別的數(shù)據(jù)同步。并可輕松提取運(yùn)用到其他的企業(yè)服務(wù)中去。
4) 多路由
文中提及的案例是一個(gè)端對(duì)端的實(shí)例。事實(shí)上,我們可以通過配置來實(shí)現(xiàn)該事務(wù)處理同步框架的多路由功能,以達(dá)到一對(duì)多的消息發(fā)布目的。串化后的包消息可以通過配置好的路由信息并通過消息隊(duì)列發(fā)送到多個(gè)端。
[1]Rod Johnson, Juergen Hoeller, Alef Arendsen, etc.The Spring Framework - Reference Documentation,URL:http://static.springsource.org/spring/docs/2.0.x/refer ence/index.html
[2]Quartz 1.x Tutorial,URL:http://quartz-scheduler.org/documentation/quartz-1.x/tutorials
[3]WebSphere MQ概述,URL:http://www-01.ibm.com/software/cn/websphere/inte gration/wmq/features/