戴施偉,周凌珉,鄭一泓
(浙江水利水電學(xué)院信息工程學(xué)院軟件工程系,浙江 溫州 325204)
OJ(Online Judge)系統(tǒng),是近十幾年隨著ACM 事業(yè)在中國(guó)的發(fā)展而引入的一種在線練習(xí)和比賽系統(tǒng),最早設(shè)計(jì)服務(wù)于ACM-ICPC 國(guó)際大學(xué)生程序競(jìng)賽的自動(dòng)判題和排名,使用者可在線提交多種程序的源代碼(如C、C++、Java),系統(tǒng)會(huì)對(duì)源代碼進(jìn)行編譯并運(yùn)行,再通過(guò)后臺(tái)數(shù)據(jù)庫(kù)的測(cè)試用例來(lái)檢驗(yàn)代碼的正確與否。隨著ACM 的發(fā)展和我國(guó)的信息化教學(xué)方式的變革,國(guó)內(nèi)一些高校也開發(fā)了屬于自己的OJ 系統(tǒng),其中也不乏有許多主流的OJ,杭州電子科技大學(xué)的HDOJ,浙江大學(xué)的ZOJ……。通過(guò)建立本校的OJ,不僅可以方便平時(shí)ACM 隊(duì)員的訓(xùn)練和競(jìng)賽模擬,還可以添加獨(dú)創(chuàng)的題目,擁有屬于本校自己的題庫(kù);在日常教學(xué)方面,OJ系統(tǒng)不僅可以提高計(jì)算機(jī)專業(yè)的學(xué)生學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)算法的積極性和學(xué)習(xí)效率,也為所有想提高自己程序算法能力的學(xué)生提供了一個(gè)練習(xí)的平臺(tái)。
結(jié)合實(shí)際需求,在框架整體的設(shè)計(jì)中本系統(tǒng)著重考慮了在高并發(fā)訪問(wèn)下的效率問(wèn)題。
系統(tǒng)使用了Spring Boot 作為開發(fā)框架,它對(duì)于Spring中存在的重量級(jí)配置問(wèn)題、項(xiàng)目的依賴管理、不支持分布式等問(wèn)題進(jìn)行了改善和優(yōu)化,精簡(jiǎn)配置的同時(shí)方便對(duì)外輸出各種形式的服務(wù)。考慮到安全性以及系統(tǒng)性能,采用判題服務(wù)與后臺(tái)服務(wù)分離的架構(gòu)優(yōu)化方案,減少服務(wù)器負(fù)擔(dān)的同時(shí)降低開發(fā)人員對(duì)系統(tǒng)維護(hù)的難度。兩者間通信采用RabbitMQ 消息隊(duì)列,既可以提高并發(fā)量,又能降低服務(wù)之間的耦合度,且具有更好的時(shí)效性。采用MySQL 進(jìn)行數(shù)據(jù)持久化存儲(chǔ),其服務(wù)靈活,快速穩(wěn)定。最后前端頁(yè)面的開發(fā)使用Vue.js框架,簡(jiǎn)潔高效。
本判題系統(tǒng)劃分為三部分:前端交互、判題系統(tǒng)、后臺(tái)系統(tǒng)(見圖1)。在前端頁(yè)面中,根據(jù)功能需要,分別對(duì)每個(gè)角色進(jìn)行界面設(shè)計(jì)。下面主要介紹判題模塊與后臺(tái)服務(wù)模塊的功能。
圖1 系統(tǒng)思維導(dǎo)圖
1.2.1 判題模塊設(shè)計(jì)
為了系統(tǒng)的安全性,判題模塊應(yīng)與后臺(tái)服務(wù)模塊相分離,使用RabbitMQ 消息隊(duì)列實(shí)現(xiàn)通信,采用心跳機(jī)制,定時(shí)向后臺(tái)服務(wù)端發(fā)送判題端系統(tǒng)信息,用于展示判題端在線情況。為了便于查看管理,判題系統(tǒng)應(yīng)地向后臺(tái)系統(tǒng)上報(bào)判題系統(tǒng)運(yùn)作狀態(tài)(見圖2)。當(dāng)收到用戶提交信息時(shí),判題系統(tǒng)應(yīng)進(jìn)行數(shù)據(jù)交互,使后臺(tái)服務(wù)端處理判題請(qǐng)求(見圖3)。
圖2 判題系統(tǒng)活動(dòng)圖
圖3 后臺(tái)處理判題請(qǐng)求活動(dòng)圖
1.2.2 后臺(tái)服務(wù)模塊設(shè)計(jì)
后臺(tái)系統(tǒng)是實(shí)現(xiàn)前端頁(yè)面操作和系統(tǒng)功能的重要模塊,本系統(tǒng)將后臺(tái)系統(tǒng)分為七個(gè)模塊,以下主要介紹四個(gè)功能模塊的設(shè)計(jì)。
⑴競(jìng)賽模塊:當(dāng)收到判題結(jié)果信息后,系統(tǒng)會(huì)對(duì)競(jìng)賽信息進(jìn)行相關(guān)更新(見圖4)。管理員和教師能在后臺(tái)添加新競(jìng)賽,并且可以設(shè)置競(jìng)賽顯示時(shí)間、開始時(shí)間、結(jié)束時(shí)間、競(jìng)賽總時(shí)長(zhǎng)等。管理員和教師也能對(duì)自己權(quán)限范圍內(nèi)的競(jìng)賽進(jìn)行修改,進(jìn)行用戶管理。設(shè)置測(cè)試賬號(hào)后可以進(jìn)行競(jìng)賽測(cè)試。設(shè)立排行榜,對(duì)競(jìng)賽成績(jī)按照編程競(jìng)賽規(guī)則排名??梢詫?duì)前臺(tái)采集的用戶數(shù)據(jù)進(jìn)行儲(chǔ)存、分析、IP 上報(bào),防止用戶作弊。提供競(jìng)賽加入功能,用戶在競(jìng)賽過(guò)程中可以直接加入開放型競(jìng)賽,對(duì)于私人競(jìng)賽可以通過(guò)房間ID 和密鑰加入。對(duì)于競(jìng)賽數(shù)據(jù)如用戶答題情況、用戶提交情況、用戶競(jìng)賽IP 數(shù)據(jù)、排行榜,可以進(jìn)行查閱和導(dǎo)出,同時(shí)競(jìng)賽的提交數(shù)據(jù)也可以進(jìn)行重新判題。
圖4 后臺(tái)系統(tǒng)處理判題結(jié)果活動(dòng)圖
⑵練習(xí)模塊:用戶可以查閱系統(tǒng)中公共類型的問(wèn)題內(nèi)容,并按答題情況差異化展示。設(shè)立排行榜,對(duì)用戶按已解決問(wèn)題數(shù)進(jìn)行排名。
⑶問(wèn)題模塊:管理員或教師能添加新的問(wèn)題,也對(duì)自己權(quán)限范圍的問(wèn)題信息進(jìn)行修改、刪除,還可以添加或刪除測(cè)試數(shù)據(jù)。
⑷討論模塊:管理員可以在系統(tǒng)設(shè)置中開啟討論區(qū),用戶能在討論區(qū)中發(fā)起討論,可以和其他用戶進(jìn)行評(píng)論互動(dòng)。
本判題系統(tǒng)數(shù)據(jù)儲(chǔ)存使用MySQL。判題系統(tǒng)模塊與后臺(tái)服務(wù)模塊分離,模塊間通信擯棄現(xiàn)有OJ系統(tǒng)普遍采用的直接讀取數(shù)據(jù)庫(kù)的方案,使用RabbitMQ消息隊(duì)列實(shí)現(xiàn)通信以提高安全性。規(guī)范數(shù)據(jù)庫(kù)編碼設(shè)計(jì),防止攻擊者通過(guò)sql 注入對(duì)后臺(tái)數(shù)據(jù)庫(kù)的數(shù)據(jù)進(jìn)行讀取、刪除、篡改。
本系統(tǒng)采用Spring Boot 自帶的定時(shí)器定時(shí)調(diào)用MySQL 自帶的mysqldump 命令來(lái)實(shí)現(xiàn)數(shù)據(jù)庫(kù)導(dǎo)出到文件,然后通過(guò)SMTP郵件發(fā)送服務(wù),將數(shù)據(jù)庫(kù)備份文件打包發(fā)送給系統(tǒng)預(yù)置的管理員郵箱,實(shí)現(xiàn)數(shù)據(jù)庫(kù)備份操作。設(shè)計(jì)時(shí)引入Docker,將判題服務(wù)封裝成容器,一方面實(shí)現(xiàn)簡(jiǎn)易部署,另一方面Docker 容器相較于直接在宿主機(jī)運(yùn)行擁有更好的安全性。
前端頁(yè)面基于Vuexy Admin Template模板開發(fā),界面基礎(chǔ)輔助色為灰黑紫,簡(jiǎn)潔大方。頁(yè)面設(shè)計(jì)中,為用戶每一類型的操作提供明確的反饋,同時(shí)也設(shè)計(jì)了對(duì)話框以及錯(cuò)誤提示。輸入框采用簡(jiǎn)單的描述文字,并使用左對(duì)齊,以符合閱讀視線規(guī)律,選擇恰當(dāng)?shù)奈淖诸伾o予用戶輸入反饋,對(duì)于錯(cuò)誤輸入給予紅色提示,對(duì)于正確輸入無(wú)提示或者給予綠色提示,對(duì)于危險(xiǎn)輸入給予黃色提示。致力于設(shè)計(jì)一款用戶友好型操作界面。
用戶界面設(shè)計(jì)為左右布局,左邊用于欄目導(dǎo)航,右邊用于欄目?jī)?nèi)容的展示,便捷高效的同時(shí)讓頁(yè)面看起來(lái)更加活躍(見圖5)。
圖5 頁(yè)面布局概覽
引入插件apexcharts 進(jìn)行對(duì)部分場(chǎng)景數(shù)據(jù)的圖形繪制,用更加直觀的數(shù)據(jù)圖展示內(nèi)容(見圖6)。
圖6 個(gè)人答題情況扇形圖
對(duì)于表格類數(shù)據(jù)進(jìn)行數(shù)據(jù)分級(jí),不同類數(shù)據(jù)采用不同配色,直觀化展示各類信息,使用戶在了解信息優(yōu)先級(jí)的同時(shí)對(duì)信息有更快速更準(zhǔn)確的定位(見圖7)。
圖7 個(gè)人歷史答題情況圖
對(duì)于用戶權(quán)限驗(yàn)證的實(shí)現(xiàn),本系統(tǒng)通過(guò)客戶端對(duì)Header(請(qǐng)求頭)中的Authorization 字段里攜帶的token令牌進(jìn)行用戶的權(quán)限校驗(yàn),客戶端發(fā)出的所有請(qǐng)求都會(huì)攜帶這個(gè)令牌,當(dāng)用戶注銷,令牌就會(huì)在客戶端進(jìn)行銷毀,由于token 無(wú)狀態(tài)的特點(diǎn),服務(wù)器不需要保存令牌的狀態(tài),可以有效降低服務(wù)器進(jìn)行數(shù)據(jù)庫(kù)查詢的次數(shù)。在用戶登錄的時(shí)候,系統(tǒng)會(huì)根據(jù)用戶的個(gè)人信息和登錄時(shí)間生成一個(gè)具有有效時(shí)間限制的token(令牌)。
本系統(tǒng)使用filter(過(guò)濾器)和interceptor(攔截器)對(duì)部分需要權(quán)限的頁(yè)面進(jìn)行授權(quán)校驗(yàn),從Header 中獲取令牌,對(duì)其進(jìn)行Base64Decode解碼后對(duì)authorization字段進(jìn)行驗(yàn)證。驗(yàn)證通過(guò)后,修改Header注入用戶ID和用戶等級(jí)信息。當(dāng)驗(yàn)證的令牌的信息無(wú)效或者錯(cuò)誤時(shí),拒絕訪問(wèn)當(dāng)前請(qǐng)求的頁(yè)面并返回授權(quán)錯(cuò)誤信息。
本系統(tǒng)采用RabbitMQ 消息隊(duì)列實(shí)現(xiàn)后臺(tái)服務(wù)與判題服務(wù)器之間的通信主要服務(wù)內(nèi)容有:向判題服務(wù)器發(fā)送判題請(qǐng)求,向后臺(tái)服務(wù)發(fā)送判題服務(wù)器返回的判題結(jié)果,實(shí)現(xiàn)心跳機(jī)制——定時(shí)向后臺(tái)服務(wù)端發(fā)送判題端的系統(tǒng)信息。MQ 服務(wù)器中的重發(fā)機(jī)制所帶來(lái)的因數(shù)據(jù)量過(guò)多導(dǎo)致內(nèi)存溢出的危險(xiǎn),可以通過(guò)調(diào)用ChannelAwareMessageListener 接口實(shí)現(xiàn)來(lái)ack 機(jī)制來(lái)消除。
判題服務(wù)器在接收RabbitMQ 消息隊(duì)列中的判題請(qǐng)求之后,將提交的代碼寫入臨時(shí)文件。根據(jù)請(qǐng)求者選擇使用的語(yǔ)言類型,選擇不同的編譯器進(jìn)行編譯并生成可執(zhí)行文件。文件生成完畢即使用題目所對(duì)應(yīng)的測(cè)試用例進(jìn)行測(cè)試,執(zhí)行完的結(jié)果保存至.out 后綴的文件中,通過(guò)用Ptrace 對(duì)進(jìn)程進(jìn)行跟蹤,執(zhí)行完畢刪除臨時(shí)文件,并使用題目所對(duì)應(yīng)的樣本標(biāo)準(zhǔn)測(cè)試結(jié)果文件和執(zhí)行生成的文件進(jìn)行比對(duì),判斷的結(jié)果通過(guò)RabbitMQ消息隊(duì)列返回。
伴隨信息化教育的普及,OJ系統(tǒng)的應(yīng)用場(chǎng)景也順應(yīng)增加,本系統(tǒng)在保證原有功能的基礎(chǔ)上,增加了對(duì)應(yīng)教學(xué)場(chǎng)景的功能,對(duì)成績(jī)和代碼的導(dǎo)出,反作弊管理的加強(qiáng)。本系統(tǒng)的后期測(cè)試結(jié)果表明所有功能運(yùn)行正常,也符合了預(yù)期性能要求。本系統(tǒng)正式運(yùn)行后在日常教學(xué)環(huán)境中得到了良好應(yīng)用,不僅能夠滿足ACM隊(duì)員的日常訓(xùn)練、模擬比賽、開展競(jìng)賽,也能作為教師開展相應(yīng)程序類設(shè)計(jì)課程的教學(xué)輔助工具,為學(xué)校所有計(jì)算機(jī)類學(xué)生和想提高自己算法能力的學(xué)生提供了一個(gè)便捷有效的平臺(tái)。