摘要:提出并實現了基于AOP技術的通用線程監控平臺#65377;借助AOP的需求空間分離實現技術,使用該平臺的原系統不必事先具有監控能力,該平臺可以在不手動改變系統源代碼的情況下通過工具自動植入系統內部,為系統注入監控功能,實現對運行線程信息的監視和對指定線程運行速度的變換,實現對整個系統運行行為的控制#65377;
關鍵詞:面向方面編程; 線程監控; Aspect C++
中圖分類號:TP339文獻標志碼:A
文章編號:1001-3695(2007)10-0249-02
0引言
監控技術是一種在軟件開發中廣泛使用的技術,通過監控可以及早發現和解決系統中存在的問題,提供系統運行時的性能數據和健康狀況,以便對系統進行優化或在必要時啟動補救措施,降低事故和災難所造成的影響#65377;目前實際應用中一般采用OOP方法實現系統的監控功能#65377;實施過程中往往需要向程序中手動安插若干用于獲取監控信息的代碼,稱之為探針代碼#65377;然而,隨著對監控信息需求的增加,探針代碼也被更廣泛地散布在軟件系統的諸多角落中[1]#65377;這樣,一旦探針需要挪動或修改,這種影響將遍布整個程序;同時,探針代碼和源程序的糾結(tangling)嚴重地破壞了軟件系統的模塊性#65380;可維護性和可擴展性[2]#65377;由此人們認識到,在使用傳統OOP技術時,監控需求的實現往往分散在程序各處,不能自然地適合單個對象或模塊[3]#65377;為解決這一問題,本文基于AOP技術,使用松散耦合的#65380;模塊化的方法實現了用于監視系統線程運行狀況#65380;控制線程運行速度的通用線程監控平臺#65377;該平臺可以在不手動改變原系統代碼的情況下,通過Aspect C++植入原系統中,提供分布式的線程監控功能#65377;其中包括監視線程當前所執行的函數名和函數執行時間,定量地改變線程的運行速度和暫停某一線程的運行,為線程運行提供日志記錄功能等#65377;本平臺適用于所有符合Java多線程編程規范的系統#65377;
1線程監控平臺GTMP
針對傳統OOP技術實現的系統監控中存在的不足,本文重點針對線程監控#65380;遵循關注點分離原則#65380;采用AOP技術提出了一個通用的線程監控平臺,稱之為GTMP(general thread monitor platform)#65377;
1.1線程監控平臺的體系結構
GTPM由三部分組成:探針AOP實現模塊#65380;自動探針生成部件#65380;監控儀表#65377;平臺所依賴的AOP工具是Aspect C++,如圖1所示#65377;
探針AOP實現模塊通過AOP編程單元Aspect封裝監控探針的實現代碼#65377;這些代碼可以是自動探針生成部件自動生成的,用于實現基本的線程監控功能#65377;同時,熟悉AOP編程的開發人員可以在該代碼的基礎上,通過線程監控管理模塊提供的API繼續編寫更加貼合業務邏輯的監控探針#65377;該模塊還集中存儲了線程的實時監控信息,對外提供這些信息的API訪問接口#65377;AOP探針的實現代碼通過調用該API,將系統中線程運行信息進行匯總;平臺的監控儀表通過調用該API獲取線程監控信息,對系統實施監控#65377;
自動探針生成部件根據用戶定制的監控對象的XML描述,自動生成探針的AOP實現代碼#65377;監控儀表可以分布式地為系統管理員提供多種線程監控信息的展現視圖,提供線程運行的控制界面#65377;
1.2線程監視探針
線程的運行依托于具體業務邏輯函數的執行#65377;函數的執行軌跡直接刻畫出線程狀態的遷移,所以對線程的監控在很大程度上就是對線程運行函數的監控#65377;線程的監控探針是針對線程業務函數實現的#65377;線程T在其業務函數FN上的AOP監控探針實現代碼如下:
advice execution(\"T∷FN(...)\"):around()
{
更新本線程當前執行函數描述信息;
更新函數的執行起始時間;
記錄函數起始執行的日志信息;
tjp->proceed(); //函數執行
記錄函數結束執行的日志信息
更新函數的執行結束時間;
}
1.3線程控制探針
控制線程的運行從本質上講,是通過AOP技術把一個阻塞線程運行的Windows事件對象(event)植入到線程的執行路徑上#65377;在運行期間,路徑上的每一個執行點都會因此增加一個定量的延時時間,線程運行速度會因此得到定量的控制#65377;
線程在threadInfo中存有一個event句柄,探針在其線程運行控制橫切代碼中加入對event“激發”(signaled)狀態的判斷#65377;每當運行到判斷代碼,線程會因event的激發狀態不同而選擇繼續執行#65380;定時睡眠或者暫停運行#65377;這個激發狀態是外部模塊通過線程監控管理模塊提供的API來動態設置的#65377;其實現代碼如下:
advice execution(\"T∷FN(...)\"):around()
{
更新本線程當前執行函數描述信息;
更新函數的執行起始時間;
記錄函數起始執行的日志信息;
阻塞等待event事件;
tjp->proceed();//函數執行
記錄函數結束執行的日志信息
更新函數的執行結束時間;
}
代碼是在1.2節中代碼的基礎上擴展而來的#65377;其中黑體字所示是調用WaitForSingleObject實現線程運行的控制,為探針注入線程控制功能#65377;
通過上述代碼可以看到,使用AOP的方法可以實現監控邏輯與業務邏輯的分離#65377;線程的OOP業務邏輯中就不需要用戶手工編寫任何監控代碼#65377;業務代碼和監控代碼的結合依賴AOP工具的weaver實現#65377;本文監控平臺使用Aspect C++實現代碼的合并#65377;
1.4平臺的通用性
觀察前面的代碼可以看出,雖然代碼是針對一個特定的線程和特定的函數實現的,但是其具有通用性#65377;不難發現,只需要簡單地修改線程名稱或者函數名稱就可以實現對其他線程和函數的監控#65377;本平臺為這些AOP代碼的實現提供了自動生成機制,用戶通過窗口界面或者XML語言,向自動代碼生成部件輸入待監控的線程名稱以及線程執行的方法名稱和描述,就能得到自動生成的探針AOP實現代碼#65377;
2監控平臺的實際應用
以一個名為rqueue的數據傳輸系統為例#65377;在使用監控平臺前,應當首先定制監控對象,即確定系統要監控的線程名和線程所執行的函數名;然后將描述好的監控對象以XML方式輸入自動探針生成部件,生成AOP監控探針實現代碼;最后通過Aspect C++編譯器和IDE開發環境的協同工作,生成具有監控功能的目標系統#65377;系統運行后,通過線程監控界面可以實現的基本監控功能如表1所示#65377;
當系統的輸入和輸出不平衡時(如輸入>輸出),系統可能會因為負載過重而陷入癱瘓#65377;通過調整輸入線程的運行速度可以使系統的負載保持均衡,服務效能將達到最優#65377;當對系統的輸入/輸出進行量化,監控客戶端通過分析便可以自動調整系統的輸入/輸出行為,實現具有反射能力的系統#65377;
3工作比較
圖2中展示了使用傳統OOP技術開發的監控代碼在程序中的散布情況#65377;每一個白色長條矩形代表程序中的一個功能模塊;每一條白色矩形中的橫線表示相應模塊中用于實現監控和日志功能的一行代碼#65377;可以看出,這些代碼出現在整個程序的各個模塊中,代碼非?;靵y#65377;
圖3是使用本文提出的監控平臺的監控代碼散布情況#65377;通過本文的監控平臺實現系統監控及日志需求時,橫切關注點被模塊化地加以實現,程序的開發#65380;擴展#65380;維護#65380;修改都因此變得更加清晰#65380;靈活和簡單#65377;
4結束語
借助本文的監控平臺,開發人員可以用與封裝組件本身相同的方式跨組件封裝和使用公共的監控服務#65377;基于AOP的先進理念,待監控系統是以松散耦合的#65380;模塊化的方法搭建的#65377;程序員無須花費大量的時間在原系統的業務邏輯中編寫監控代碼,可以動態地修改靜態的OO監控模型,構造出一個能夠不斷增長以滿足新增監控需求的系統#65377;可以預見,隨著AOP技術的發展和AOP開發環境的日漸完善,在不遠的將來,AOP技術將深刻地影響軟件開發方法#65377;
參考文獻:
[1]MAHRENHOLZ D, SPINCZYK O, SCHRDERPREIKSCHAT W. Program instrumentation for debugging and monitoring with Aspect C++[C]//Proc of the 5th IEEE Int’l Symp on ObjectOriented Realtime Distributed Computing. Washington DC: IEEE Computer Society, 2000:249-256.
[2]曹東剛,梅宏.面向Aspect的程序設計——一種新的編程范型[J].計算機科學,2003,30(9):510.
[3]KICGALES G. Aspectoriented programming[C]//Proc of the European Conf on ObjectOriented Programming(ECOOP). 1997.
[4]高海洋,陳平.AOP綜述[J].計算機科學,2002,29(10):133135.
[5]WALKER R J, BANIASSAD E L A, MURPHY G C. An inital assessment of Aspect2 oriented programming[C]//Proc of the 21st International Conference on Software Engineering. Los Angeles:[s.n.], 1999.
[6]TZILLA E, FILMAN R E, BADER A. Aspect2 oriented programming[J]. Communications of the ACM, 2001,44(10):95-97.
[7]GOADY Y, KICZALES G, FEELEY M, et al. Using AspectC to improve the modularity of pathspecific customization in operating system code[C]//Proc of the 8th European Software Engineering Conference the 9th ACM SIGSOFT Symposium on the Foundation of Software Engineering. Vienna:[s.n.], 2001:88-98.
[8]COADY Y, KICZALES G, FEELEY M, et al. Structuring operating system Aspects[J]. Communications of the ACM, 2001,44(10):79-82.
[9]HANNEMANN J, KICZALES G. Design pattern implementation in Java and AspectJ[J]. ACM SIGPLAN Notics, 2002,37(11):161173.
[10]BAKER J, HSIEH W. Runtime Aspect weaving through metaprogramming[C]//Proc of the 1st International Conference on AspectOriented Software Development.New York:ACM Press,2002:86-95.
[11]AspectC++ addin for Microsoft Visual C++[EB/OL].http://www.puresystems.com.
[12]Aspect C++ language reference[EB/OL].http://www.puresystems.com.
[13]MAES P. Concepts and experiments in computational reflection[C]//Proc of the ACM Conference on ObjectOriented Programming, Systems, Languages and Applications. New York: ACM Press, 1989:147155.
“本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文”