管賦勝
[摘要]在分析源代碼自動評測系統設計的基礎上,進一步闡述如何實現系統的高可用性和高性能。從以下三個方面:評測系統、集群技術和性能測試介紹實踐經驗。
[關鍵詞]評測系統集群技術響應時間吞吐量
中圖分類號:TP3文獻標識碼:A文章編號:1671-7597(2009)0820048-02
在程序設計語言、數據結構、算法設計與分析教學中,程序設計上機練習是必不可少的。由此帶來教師在平時輔導中批改學生源代碼作業量大,并且也存在一些個人主觀因素或者不能注意到學生一題多解的情況,導致反饋的效率不高,影響學生學習的積極性。
目前國內提供的練習網站,往往只是針對部分群體的訓練使用,無法在自己課堂上充分利用。為此研究開發了基于集群技術的源代碼自動評測系統,它是在Linux 2.6內核操作系統上,JVM1.6.x,Apache 2.2.x,Tomcat6.0.x環境中,使用JAVA編寫Servlet,用JSP編寫動態網頁,結合Linux系統編程完成的。綜合運用了多種編程技術如:多線程、系統調用、管道技術等。
下面介紹一下系統的實現過程。
一、源代碼自動評測系統
系統需要完成以下任務:學生注冊登錄后,瀏覽題目,選擇自己熟悉的編程語言完成試題要求,提交答案源代碼。系統接受提交命令后,把源代碼生成為臨時文件(一般存于系統臨時目錄,文件名為系統解題id號,擴展名為自己選擇語言的標準名,如code_1234.cpp,然后等待評測。
系統在檢查到有源代碼生成后,會執行編譯命令,如果編譯不成功則轉到錯誤處理程序,匯報編譯錯誤類型,停止執行,反饋信息。編譯成功,則轉到執行模塊,根據生成答案和系統標準答案(均是文件形式)比對,確定提交答案的實際執行情況。一般會有“答案錯誤”、“超時”、“超內存”等情況。同時系統把編譯和執行情況反饋給用戶。
由此可以看出,源代碼自動評測系統至少應該包括這樣幾個模塊:WEB服務模塊、自動編譯模塊、自動評測模塊或者其它可以擴展模塊。其中前端服務是注冊模塊,后端服務是自動編譯和評測模塊。后臺數據庫服務選擇MySQL作為支持。
1.數據庫設置。
根據系統的分析設計,至少需要建立以下表:用戶信息表,題目表,比賽表,狀態表,日志表。
2.WEB服務模塊。
使用JAVA編寫Servlet,用JSP編寫動態網頁,在頁面中調用Servlet服務。
3.自動編譯模塊。
系統支持C,C++,JAVA,Pascal編譯。為了防止編譯過程時間過長,可以分配給每一待編譯源代碼時間最大值(可以根據需要調整)。
4.自動評測模塊。
(1)時間計算。使用以下簡短代碼即可測試,如果精度再放寬點可以用Date().getTime()獲得時間,精度要求更高,需要讀取CPU的時鐘周期數再根據頻率換成時間。
long starttime=System.currentTimeMillis(); //獲取最初時間
doSth(); //測試的代碼段,通常可以將主要算法封裝在這里
long endtime=System.currentTimeMillis();//獲取運行結束時間
System.out.println("程序運行時間:"+(endtime-starttime)+"ms”);
當然為了限制時間資源的無限制占用,可以加入Thread.sleep(delay),
到達指定的時間立即停止答案程序的運行,并返回超時信息等。
(2)結果反饋。評測系統運行結果存儲在后臺數據庫中,如程序運行時長,占用內存空間等。特殊結果給出提示,方便用戶修改源代碼。
(3)執行安全。有一些文件需要通過WEB程序執行或者刪除,但這些文件JSP又沒有權限訪問,給用戶使用程序帶來不便,這時需要借助于sudo來提高權限。
一般當前的Apache的用戶是nobody,Tomcat服務的用戶是誰呢?這取決啟動時的執行startup.sh命令的用戶。何不把用戶統一設置成root?這樣太不安全,而sudo運行用戶程序過程中,只需要注意其運行權限的分配問題。例如,限制用戶程序網絡使用權限,限制用戶程序非法調用系統函數關機、重啟、格式化硬盤等操作。當然,在編譯階段,編譯模塊也同時在頭文件中將有關危險系統調用函數屏蔽掉。
另一個安全上的考慮是代碼作弊,系統提供了一個相似度的檢查程序,可以有效地查出作弊代碼。
5.擴展模塊(競賽管理,課程管理)
必要時的考試或者競賽可以有效地促進學生檢驗當前階段的學習,所以在系統中增加了競賽管理模塊。對于用戶而言,一旦參加競賽,權限就會受到一些限制,并且無法自行脫離參賽狀態。必須等到競賽結束才能回復到完整權限。計分方式以每一個問題的最后一次發送代碼為評分依據。
在幾百人比賽中部分學生反映頁面打不開,或者提交代碼后系統1分鐘內無法回饋信息。針對以上問題,查看了Tomcat日志,Linux系統日志,評測系統日志發現,在集中提交時段如一題臨近結束時間2分鐘內200個左右的提交,有20個左右沒有處理。這給系統設計者提了一個更高要求的,如何在并發提交量較大時保證服務的可用性和性能。
經過實踐發現,解決這個問題,可以采用集群技術。
二、集群技術的應用
(一)編譯、評測模塊服務器集群
以Linux核心層集群技術和安全技術為基石,構建一個在Internet服務器中將負載分給多個服務器分擔,以解決Internet服務器面臨的大量并發訪問造成的CPU或I/O的高負載問題。
每一臺計算機上安裝Linux操作系統,并要在Linux操作系統中安裝C編譯器和C的LIB庫。在配置TCP/IP時,給計算機配置IP地址使集群服務器的計算機能進行相互通訊。
在進行配置服務器時推薦使用MPICH軟件去執行分布式的并行處理應用。mpich是由Argonne National Laboratory和Mississippi State University合作開發的。這樣在修改編譯模塊程序時記得 #include "mpi.h"庫。
(二)Tomcat集群
Tomcat 6中的集群使一組局域網上的Tomcat實例(稱為集群)在用戶看起來是單一服務器。這使不同的服務器之間能分布地工作,稱為負載平衡。Tomcat 6處理集群的方式利用了便宜的高速LAN互聯來共享多個服務器的計算資源。這就是按比例擴展(scaling out)和線性擴展方法。通過使集群服務器明顯地處理更多的并發請求,可以解決可擴展性問題。Tomcat服務器通過使用AJP連接器和Apache Web服務中mod_proxy(更低版本使用的是mod_jk)插件來支持線性擴展。Tomcat 6集群可用來實現一個高可靠性問題,在這種情況下會出現以下情況:
1.指定給崩潰服務器的請求轉寄到集群中另一臺功能正常的服務器。
2.最初的請求由功能正常的服務器處理。
3.失敗的Tomcat服務器邏輯上從集群刪除,請求不再會傳給它。
4.當失敗的Tomcat服務器恢復邏輯上它被添加集群中,再一次用來處理輸入的請求。
但如何知道,原來的“服務器停在哪里”呢?并要繼續從停止的地方開始。這要求信息的同步和共享。在JAVA EE兼容的Servlet/JSP容器中,有個普遍認可的約定可以利用來跟蹤WEB應用程序的狀態信息。Tomcat 6集群實現利用它來提供故障轉移能力。
(三)MySQL服務器集群
MySQL Cluster技術允許在無共享的系統中部署“內存中”數據庫的Cluster。通過無共享體系結構,系統能夠使用廉價的硬件,而且對軟硬件無特殊要求。此外,由于每個組件有自己的內存和磁盤,不存在單點故障。
MySQL Cluster由一組計算機構成,每臺計算機上均運行著多種進程,包括MySQL服務器,NDB Cluster的數據節點,管理服務器,以及(可能)專門的數據訪問程序。
數據保存在“NDB存儲服務器”的存儲引擎中,表(結構)則保存在“MySQL服務器”中。源代碼自動評測系統通過“MySQL服務器”訪問這些數據表,集群管理服務器通過管理工具(ndb_mgmd)來管理“NDB存儲服務器”。
三、性能測試
到目前為止,只是探討了如何安裝、配置一個集群服務系統,無論在哪個環節中的安裝與調整,源代碼自動測評系統的性能提升如何,有效的性能測試是至關重要的。
性能對一個WEB站點意味著什么,從用戶視角WEB性能可歸結為WEB頁面處理有多快。而對于一個設計者,需要準確量化WEB站點性能。
重點從以下兩個性能方面來測試:響應時間、吞吐量。測試分類為3類:負荷測試、壓力測試、連續時間的運行測試。需要指出的是負荷測試和壓力測試往往被錯誤地互換使用。負荷測試是在正常工作狀態能承擔的“最高負荷”,而壓力測試意味者超負荷,直至系統崩潰,獲得的錯誤類型可能是WEB服務器拒絕連接,JAVA虛擬機耗光內存,數據庫連接失敗或其它現象。
有很多這樣的性能測試應用程序,以JMeter為例,盡管它是開源軟件,仍然是出色的可解決方案之一,尤其是對JDBC數據源和JAVA對象進行負荷測試。任何JMeter會話核心是測試計劃,每個測試計劃中第一個元素是線程組,線程組是一組元素的集合,每個線程有自己的一組JAVA線程,可以進行相關測試配置,形成一個完整的計劃。啟動測試后結束后,可以在窗口顯示響應中接收的數據和負荷時間(毫秒)、HTTP響應代碼等。默認測試運行一次,可以將線程組改為更高值如200個線程(也就同時模擬200個用戶),在它們之間有1s的ramp up period(即模擬1s內200個用戶同時訪問)。
在完成初步的性能測試后,發現集群服務下的源代碼自動測評系統web應用程序運行不理想,不要急著丟棄多余硬件等,此時主要是分析導致性能提升幅度不大原因,可以分環節測試如JDBC部分。并查看各服務部分的日志,最后確定影響系統性能的瓶頸,就可以明確處理,從而更有效地建立基于集群技術的源代碼自動測評系統。
參考文獻:
[1]魯靜軒、孫晶、李元嵩,程序在線評測系統的設計與實現.
[2]孫敏,基于Linux的集群.
[3](美)Vivek Chopra、Sing Li、Jeff Genender著,Aapache Tomcat 6高級編程.
[4]徐千洋,Linux C函數庫參考手冊.