董愛強(qiáng),齊志超,馮 揚(yáng),張立新
?。ū本┲须娖杖A信息技術(shù)有限公司, 北京 100192)
摘 要: 設(shè)計了一種Jboss中間件異常事務(wù)恢復(fù)功能,并實現(xiàn)了maven工程中交易服務(wù)的異常事務(wù)處理和恢復(fù)過程,該過程能在斷電、宕機(jī)、程序故障等異常情況發(fā)生時,及時恢復(fù)最近一次正常工作的交易服務(wù)狀態(tài)和數(shù)據(jù)庫數(shù)據(jù)。并通過日志記錄整個異常狀態(tài)的發(fā)生和恢復(fù)過程。通過測試證明,該設(shè)計與實現(xiàn)是一種有效的中間件異常事務(wù)狀態(tài)恢復(fù)的過程,能夠為中間件正常運(yùn)行提供可靠支持和日志依據(jù)。
關(guān)鍵詞: 中間件;maven工程;交易服務(wù);異常事務(wù);數(shù)據(jù)恢復(fù)
0 引言
中間件作為國網(wǎng)云建設(shè)的支持性項目,根據(jù)云建設(shè)采用的X86集群模式[1],分析了目前采用較多的weblogic等其他類型中間件的利弊。國網(wǎng)公司自主開發(fā)的具有自主知識產(chǎn)權(quán)的新一代Jboss中間件產(chǎn)品,可以適應(yīng)云建設(shè)和管理的要求,實現(xiàn)集群資源共享,降低成本,提高資源利用率。
在中間件運(yùn)行期間出現(xiàn)異常事務(wù)狀態(tài),例如宕機(jī)等導(dǎo)致中間件不能正常工作,從而對云平臺的使用帶來安全隱患。讓故障設(shè)備盡快恢復(fù)到正常狀態(tài)是本文設(shè)計和實現(xiàn)的主要內(nèi)容。
1 技術(shù)背景
1.1 交易服務(wù)與恢復(fù)
交易服務(wù)屬于中間件的一個重要功能模塊,開啟此功能可以處理因異常運(yùn)行狀態(tài)產(chǎn)生的中斷事務(wù)(transaction)。當(dāng)服務(wù)器再次重新啟動后,交易服務(wù)模塊會分析故障前的日志記錄,根據(jù)日志復(fù)原事務(wù)現(xiàn)場工作狀況,再次提交故障前中斷的事務(wù),恢復(fù)之前事務(wù)和沒有保存的數(shù)據(jù)[2],從而實現(xiàn)對交易的恢復(fù)。
1.2 功能設(shè)計
交易服務(wù)恢復(fù)主要兩個重要功能模塊:事務(wù)日志記錄和事務(wù)恢復(fù)的功能。該功能模塊需要無縫接入到當(dāng)前中間件模塊中,所以需要實現(xiàn)org.jboss.as.controller.Extension擴(kuò)展接口。這是中間件啟動時加載擴(kuò)展模塊的必要條件。業(yè)務(wù)在接口的initialize()方法中實現(xiàn),相當(dāng)于一個入口方法。為了不影響中間件的啟動進(jìn)程,需要另開一個線程實現(xiàn)業(yè)務(wù)邏輯,用戶獲取數(shù)據(jù)庫連接需要讀取配置文件。連接分兩種:
第一種是用戶配置連接信息,程序讀取配置信息后創(chuàng)建連接即可;第二種是配置jndi獲取連接,通過jndi名獲取數(shù)據(jù)庫連接。第二種方式由于獲取連接時中間件數(shù)據(jù)源模塊還沒加載完成,獲取不到連接,此時可設(shè)計一個循環(huán)等待的過程,直到中間件數(shù)據(jù)源模塊加載完成后才能通過jndi獲得連接,然后跳出循環(huán),執(zhí)行恢復(fù)操作??紤]到性能原因,如果jndi數(shù)據(jù)源本身存在問題,可能永遠(yuǎn)獲取不到,最好設(shè)置一個超時參數(shù),表示通過jndi獲取數(shù)據(jù)源的最長等待時間,超出這個時間就直接跳出循環(huán)。對于有可能出現(xiàn)重復(fù)啟動問題,事務(wù)會重新提交,要解決這個問題,需要在處理完事務(wù)后做結(jié)束標(biāo)記處理,并標(biāo)記事務(wù)是正常提交還是重啟服務(wù)后的事務(wù)提交。對于添加事務(wù)日志功能,因為涉及到多線程操作,所以將日志的id以線程id表示。
1.3 數(shù)據(jù)恢復(fù)
數(shù)據(jù)恢復(fù)時,首先需要定義一個TradeExtension類實現(xiàn)org.jboss.as.controller.Extension擴(kuò)展接口,業(yè)務(wù)在接口的initialize()方法中實現(xiàn),為了不影響中間件的啟動進(jìn)程,需要另開一個線程實現(xiàn)業(yè)務(wù)邏輯,用戶獲取數(shù)據(jù)庫連接需要讀取配置文件,連接分兩種。其實現(xiàn)方法與上節(jié)的實現(xiàn)方法相同。定義Conn類和ConnManager類主要是讀取配置文件獲取連接信息,適合單個長事務(wù)[3]的恢復(fù)。
2 系統(tǒng)啟動
2.1 Maven工程構(gòu)建
中間件中所有的模塊都需要構(gòu)建成maven工程,maven工程構(gòu)建必須滿足特定的條件才能在中間件啟動過程中正確加載。jboss中自帶maven程序,啟動maven工程是第一步工作。
2.2 加載事務(wù)模塊
中間件啟動后需要加載事務(wù)模塊和處理事務(wù)日志。加載模塊先執(zhí)行standealone的啟動腳本,執(zhí)行jboss-modules.jar,然后執(zhí)行jboss.as.standalone模塊,解析此模塊的描述文件,執(zhí)行jboss.as.server的Main類的main方法,此模塊調(diào)用jboss.as.controller模塊解析standalone的配置文件,加載擴(kuò)展模塊,并調(diào)用每個擴(kuò)展模塊的擴(kuò)展接口方法。對于交易模塊來說,實現(xiàn)了擴(kuò)展接口的初始化方法initalize(),此方法中新開啟一個子線程處理交易恢復(fù)業(yè)務(wù)。
2.3 處理事務(wù)日志
處理事務(wù)日志先調(diào)用日志工具類的getNearFileName()方法獲得離當(dāng)前時間最近的日志文件,如果此文件不存在,則直接返回,調(diào)用getExeSqlList()方法獲取所有要執(zhí)行的記錄包含sql語句以及連接信息,遍歷每一條記錄獲取sql語句以及連接信息,創(chuàng)建數(shù)據(jù)庫連接,用sql語句創(chuàng)建事務(wù),然后提交事務(wù)。創(chuàng)建文件輸出流FileWriter修復(fù)每一條執(zhí)行的記錄,最后強(qiáng)制關(guān)閉文件流。
2.4 添加事務(wù)日志
事務(wù)日志記錄可實現(xiàn)日志模塊配置、日志級別設(shè)置、日志輪轉(zhuǎn)設(shè)置、日志輸出方式配置,并可實現(xiàn)自定義日志擴(kuò)展。日志管理內(nèi)容包括執(zhí)行日志記錄、獲取模塊描述、讀取xml文件元素、解析日志元素、解析根日志元素、添加資源屬性描述、添加設(shè)置參數(shù)描述、覆蓋服務(wù)。
首先定義一個日志類TradeLog,包含的屬性有projectName:項目名稱,id:日志唯一編號,sql:事務(wù)執(zhí)行的sql語句,result:是事務(wù)前日志還是事務(wù)后日志,connid:對應(yīng)數(shù)據(jù)庫連接信息。定義一個處理日志的工具類LogTool,其主要作用是添加日志,初始化日志路徑,獲得當(dāng)前日志文件名稱(如果當(dāng)前文件不存在,就會創(chuàng)建當(dāng)前日志文件),讀取距離當(dāng)前時間最近的日志文件,獲取文件中需要執(zhí)行的sql語句[5]。
2.4.1 日志格式
日志文件名稱:yyyymmddhh.log
日志格式:
([a-z]|[A-Z][0-9])*\|[0-9]{1,19}\|([a-z]|[A-Z][0-9])*\|[0-9]{1,10}
([a-z]|[A-Z][0-9])*\|[0-9]{1,19}\|ready-commit
([a-z]|[A-Z][0-9])*\|[0-9]{1,19}\|commit
第一條日志表示事務(wù)開始后提交前的日志,后面的日志表示提交后的日志。
日志狀態(tài):用戶請求數(shù)據(jù)庫操作,如果存在事務(wù)開始日志、事務(wù)準(zhǔn)備提交日志以及事務(wù)提交日志,則為正常狀態(tài);如果只存在事務(wù)開始日志,則不進(jìn)行恢復(fù)操作;如果存在事務(wù)開始日志和事務(wù)準(zhǔn)備提交日志,則進(jìn)行恢復(fù)操作。
日志周期:一個小時生成一個文件。每次讀取與當(dāng)前時間最近的文件。
日志路徑:%JBOSS_HOME%\standalone\log\trade_log。
2.4.2 日志添加過程
日志添加,包含事務(wù)提交前添加日志和事務(wù)提交后添加日志。
事務(wù)提交前添加日志,首先定義一個日志類TradeLog,包含的屬性有projectName:項目名稱,id:日志唯一編號,sql:事務(wù)執(zhí)行的sql語句,result:是事務(wù)前日志還是事務(wù)后日志,connid:對應(yīng)數(shù)據(jù)庫連接信息。定義一個處理日志的工具類LogTool,主要作用是添加日志,初始化日志路徑,獲得當(dāng)前日志文件名稱(如果當(dāng)前文件不存在,就會創(chuàng)建當(dāng)前日志文件),讀取離當(dāng)前時間最近的日志文件,獲取文件中需要執(zhí)行的sql語句。
在事務(wù)開始后,創(chuàng)建一個Log對象,將要執(zhí)行的sql語句賦值到Log對象中,將當(dāng)前線程的id賦值到Log對象的id屬性中,創(chuàng)建一個文件輸出流FileWriter,用于追加文件信息,將日志信息轉(zhuǎn)化為固定格式的字符串,調(diào)用FileWriter的write()方法將這條記錄寫入到文件中,然后強(qiáng)制關(guān)閉文件流。待用戶提交事務(wù)后,創(chuàng)建Log對象,將當(dāng)前線程id賦值到id屬性中,創(chuàng)建事務(wù)結(jié)束字符串信息,調(diào)用文件輸出流將信息追加到文件中。
2.4.3 日志加載類型
用戶在添加事務(wù)日志時需要添加三種類型的日志,在LogType枚舉類型中有定義,分別為START-COMMIT、READY-COMMIT以及DONE-COMMIT。在事務(wù)開始后需要添加START-COMMIT類型的日志,此日志主要記錄了所要執(zhí)行的sql集,在事務(wù)恢復(fù)時執(zhí)行。在事務(wù)準(zhǔn)備提交的時候需要添加READY-COMMIT類型的日志,表示此事務(wù)準(zhǔn)備提交,主要作用是保證事務(wù)的原子性。事務(wù)提交完成后,添加DONE-COMMIT類型的日志,表示提交完成。
3 事務(wù)恢復(fù)
中間件可選擇是否開啟交易服務(wù),開啟交易服務(wù)后,交易管理器動態(tài)監(jiān)控當(dāng)前正在執(zhí)行的交易,并以日志的方式記錄在系統(tǒng)中。在全局事務(wù)沒有完成提交之前,如果系統(tǒng)出現(xiàn)故障,則重啟中間件應(yīng)用服務(wù),交易管理器將根據(jù)日志記錄的故障發(fā)生時交易的狀態(tài),不僅僅恢復(fù)數(shù)據(jù),還要對交易的異常事務(wù)進(jìn)行恢復(fù)[4]。事務(wù)恢復(fù)過程如圖1所示。
3.1 實現(xiàn)過程
事務(wù)恢復(fù)實現(xiàn)過程,首先定義一個TradeExtension類實現(xiàn)org.jboss.as.controller.Extension擴(kuò)展接口(這是sg-aps啟動時加載擴(kuò)展模塊的必要條件),業(yè)務(wù)在接口的initialize()方法中實現(xiàn)。為了不影響中間件的啟動進(jìn)程,需要另開一個線程實現(xiàn)業(yè)務(wù)邏輯,用戶獲取數(shù)據(jù)庫連接需要讀取配置文件。連接分兩種:第一種是用戶配置連接信息,程序讀取配置信息后創(chuàng)建連接即可;第二種是配置jndi獲取連接,通過jndi名獲取數(shù)據(jù)庫連接。第二種方式由于獲取連接時中間件數(shù)據(jù)源模塊還沒加載完成,肯定獲取不到連接,此時設(shè)計一個循環(huán)等待的過程,直到中間件數(shù)據(jù)源模塊加載完成后才能通過jndi獲得連接,然后跳出循環(huán),執(zhí)行恢復(fù)操作??紤]到性能原因,如果jndi數(shù)據(jù)源本身存在問題,則可能永遠(yuǎn)獲取不到,因此最好設(shè)置一個超時參數(shù),表示通過jndi獲取數(shù)據(jù)源的最長等待時間,超出這個時間就直接跳出循環(huán)。定義Conn類和ConnManager類主要是讀取配置文件獲取連接信息。
3.2 日志記錄
根據(jù)添加日志的方法先添加日志,初始化日志路徑,獲得當(dāng)前日志文件名稱,讀取事務(wù)恢復(fù)前最近的日志文件,獲取文件中需要執(zhí)行的sql語句,執(zhí)行該語句恢復(fù)數(shù)據(jù),生成新的日志記錄。默認(rèn)情況下是在%JBOSS_HOME%\trade_log下,也可自行配置。
4 實現(xiàn)與測試
4.1 構(gòu)建環(huán)境
構(gòu)建系統(tǒng)測試實現(xiàn)環(huán)境,采用junit測試,總共測試4個場景:
(1)maven編譯過程;
(2)集成到整個工程的發(fā)布過程;
?。?)客戶端添加日志過程;
?。?)中間件重啟恢復(fù)數(shù)據(jù)過程。
4.2 交易編譯
首先,編譯maven工程打開命令窗口,接著進(jìn)入到模塊根目錄,再運(yùn)行mvn celan install。如果命令窗口沒有報錯,根目錄下生成target目錄,進(jìn)入目錄可以看到編譯好的jar包,如圖2所示。
4.3 交易模塊發(fā)布
首先打開命令窗口,接著進(jìn)入到aserver根目錄,再運(yùn)行build clean install。在aserver/build/target/目錄下生成發(fā)布版本,進(jìn)入到發(fā)布版本模塊的modules/org/jboss/as/目錄下有發(fā)布成功的交易模塊代碼,如圖3所示。
4.4 交易日志生成
安裝客戶端代碼后執(zhí)行代碼控制臺沒有報錯,打開到指定的日志目錄(目錄位置在程序運(yùn)行時打印出來),有當(dāng)前日志生成,日志里有一天未完成的事務(wù)記錄。日志生成界面如圖4所示。
4.5 異常事務(wù)狀態(tài)恢復(fù)
首先,打開數(shù)據(jù)庫確認(rèn)日志中未完成的記錄不存在,接著在配置文件standalone.xml中添加交易服務(wù),之后運(yùn)行standalone模式的的啟動腳本。打開數(shù)據(jù)庫客戶端,查詢數(shù)據(jù)庫記錄,未完成的記錄被添加到數(shù)據(jù)庫中了。圖5為數(shù)據(jù)庫恢復(fù)前結(jié)果,圖6為數(shù)據(jù)庫恢復(fù)后結(jié)果。
以上測試結(jié)果初步證明交易服務(wù)的恢復(fù)功能設(shè)計有效可行,在Windows和Linux平臺下測試,均能靈活實現(xiàn)跨平臺可移植[6]。能夠滿足國家電網(wǎng)對中間件應(yīng)用服務(wù)器集群數(shù)據(jù)恢復(fù)功能性能等的整體要求。實現(xiàn)便捷在嵌套事務(wù)處理上具有一定優(yōu)勢[7],適合云平臺建設(shè)。
根據(jù)國家電網(wǎng)的要求,該設(shè)計和實現(xiàn)還需要進(jìn)一步在安全性[8]和兼容性,大數(shù)據(jù)壓力測試等方面進(jìn)行進(jìn)一步的測試,以及與本系統(tǒng)其他功能的聯(lián)調(diào)。在和其他系統(tǒng)聯(lián)調(diào)后,關(guān)鍵功能、性能指標(biāo)還需多次在不同單位進(jìn)行測試和評估。
5 結(jié)束語
異常事務(wù)處理和恢復(fù)作為中間件應(yīng)用服務(wù)器的交易服務(wù)設(shè)計和開發(fā)的重要內(nèi)容,在整個中間件系統(tǒng)的運(yùn)行中起到了關(guān)鍵作用,為整個中間件的正常運(yùn)行提供了可靠支持。該功能的穩(wěn)定性和可靠性直接關(guān)系到中間件產(chǎn)品的性能。
本文提供的異常事務(wù)狀態(tài)恢復(fù)和管理的設(shè)計和實現(xiàn)方式,對中間件這類問題的解決提供了參考和借鑒。
參考文獻(xiàn)
[1]馮揚(yáng).云安全技術(shù)研究.電力信息與通信技術(shù)[J].2014,12(1).
[2]魏茂喜,賀貴明,吳元保.事務(wù)管理器的事務(wù)恢復(fù)處理[J]. 微型機(jī)與應(yīng)用,2004,23(4):14-17.
[3]李建,羅軍.一種基于工作流的長事務(wù)恢復(fù)方法的研究[J]. 信息技術(shù),2009(7):152-155.
[4]陳國寧,李陶深,廖國瓊.基于Savepoint機(jī)制和日志的協(xié)作設(shè)計事務(wù)的恢復(fù)方法[J].計算機(jī)工程,2004,30(9):58-60.
[5]王耀飛,李林,康衛(wèi).實時數(shù)據(jù)庫主動計算的設(shè)計與實現(xiàn)[J].電子技術(shù)應(yīng)用,2014,40(8):134-139.
[6]鐘舟.對象交易中間件的設(shè)計與實現(xiàn)[D].成都:電子科技大學(xué),2008.
[7]肖迎元,劉云生,廖國瓊.基于嵌套事務(wù)模型的實時數(shù)據(jù)庫系統(tǒng)故障恢復(fù)模式[D].武漢:華中科技大學(xué)計算機(jī)學(xué)院,2005.
[8]李珊珊,陳運(yùn),姚文斌.基于加密中間件的iSCSI遠(yuǎn)程鏡像方法的研究與實現(xiàn)[J].電子技術(shù)應(yīng)用,2011,37(9):