我這校區新的微機老師斗志昂揚,准備讓我們這學校萎靡的信息技術競賽重振雄風。然后有一次我半開玩笑地說建一個自己的OJ吧,老師也就鼓勵我去做了。
開什么玩笑……!我可是馬上要參加NOIP的人!
於是老師說,慢慢來吧。
嗯,正好我也有興趣,那就慢慢來吧。先策划一下。
然后我就被嚇到了。
(注:以下內容純屬紙上談兵,若坑了請善待><)
零、服務器何在
話說老師辦公室里有N台學校淘汰下來的機子,用來做服務器再合適不過了,隨便捉一台來裝上Linux(學會Linux真是有必要),放在老師辦公室24小時掛着,還不用交電費。
至於訪問,暫時只准備學校內網用。雖然破掉了學校的總網關,可以映射端口,然而80端口被電信殘忍地封掉了。准備以后要外網訪問就用VPN連上我那VPS,VPS再反向代理讓公網訪問……
因為OJ還早,所以上面放了個App Inventor給FTC機器人競賽的用。啊,物盡其用=。=
一、拿來,還是原創
首先我先搜索了一下現成的OJ。我是覺得Vijos、Codevs什么的相當精美好用,然而……不開源啊。
看上了一個叫hustoj的開源OJ,演示站點感覺還不錯,然而——
真實效果丑哭了好嗎!尤其是后台!絕對是我打開方式不對……
然后后台添加個題目,提交試試,然后是無盡的等待編譯……目測是哪個服務沒配置好。懶得檢查了,反正我愛折騰,讓我自己寫個!
二、技術困難,和腦補的應對措施
建一個OJ,感覺技術困難還是挺多的……在這把能想到的列舉一下,附帶臆測的解決方案。其中部分借鑒了hustoj和網上(主要是知乎)的信息。
0.整個OJ的運行架構
目前我想的是Web+n個分離的評測機。當然Web也可能兼任一個評測機。
Web:PHP + MySQL
評測機:Python + CPP + MySQL
其中Web部分平台應該Windows和Linux都可以,而評測機應該不能跨平台,因為調用的系統API不同。想了想決定評測機放在Linux平台,主要是Linux服務器更主流,開發時網上資料多些(對我這技術渣Google是必備的)。而且安全方面也好操作些。
1.OJ運行流程
目前想象的是這樣:
用戶提交-->Web界面-->Web服務器在數據庫中新建評測-->Web服務器找到應輪到的評測機,下發評測指令和相關數據(用戶代碼、標准輸入輸出)-->評測機開始評測,向數據庫寫入結果-->用戶在Web界面獲取結果
上面是我亂想的……真的OJ是不是這樣也不清楚……因為我只看了hustoj的一點點代碼。
2.安全問題
這是個重要問題……要是來一發惡意代碼,整個網站掛掉了……甚至服務器完全淪陷。俗話網上說得好,畢竟別人寫代碼給你運行,就算限時1秒都能干很多事了。
現在對於這個重大問題,我的方案是:
0.首先,必須在fork時限制使用的內存和CPU時間,然后禁止網絡訪問,權限給它弄到幾乎為0。
1.然后,聽聞Docker的大名,雖然我到現在一次都沒有用過……准備把程序放在Docker里面,只留一個讀寫評測數據的目錄和母機互通。
2.如果Docker啟動速度非常快的話……那就每次評測都重啟一次Docker虛擬機。
3.如果Docker啟動速度沒那么快……那就要在母機程序中加一個監測的,狀態不對再重啟虛擬機。(還是非常快)
4.母機程序准備用Python(因為好寫),虛擬機內程序用C++(因為快又方便控制資源)。
5.Docker運行用戶要用nobody什么的……
6.要限制文件讀寫大小,和母機互通的目錄准備弄在一個掛載的限制大小的鏡像里。
#綠色為20151101更新
然而以上純屬臆想……我是否方了還需時間驗證……(〃∀〃)
3.其他的小問題
其他還有一些小問題,比如如何監測評測機的在線狀態,掛了自動轉移……還有Web界面讓我這個美工廢怎么動刀……
但這都是小問題了,畢竟專業挖坑三百年,只管挖坑不管填(つд⊂)