于述春, 叶 青, 王 鹏
(怀化学院 计算机科学与工程学院,湖南 怀化 418008)
基于消息队列的在线编译系统
于述春,叶青,王鹏
(怀化学院 计算机科学与工程学院,湖南 怀化418008)
摘要:在线编译系统是程序设计类网上课程练习或程序设计竞赛类网站的一个关键组件,其性能直接影响到系统或网站所支持的并发用户数.基于消息队列的在线编译系统将在线编译服务与Web服务器变成松耦合结构,因而可通过部署更多套在线编译服务来支持大用户量并发访问.论文提出了以消息队列作为Web服务器和在线编译系统的中间组件,分析了二者交互的接口技术JMS以及activemq-cpp,并研究了对于C/C++程序如何限制其运行时间和所用内存.测试结果说明了这种松耦合结构是可行的.
关键词:消息队列;JMS;activemq;在线编译
1引言
编程类在线练习因为方便及练习结果可马上知道而大受学习者欢迎[1,3,13],特别是随着MOOC[12,14]课程的兴起,程序设计类在线课程数量就更多了,因而访问量上升,原来未考虑的性能问题现在变成了必须考虑并解决的问题.这种在线编译与评判技术最先被很多ACM竞赛类网站采用,作为提供练习与交流的工具.在网站访问量少,并发访问数未达到临界点时,系统根本不受在线编译性能影响[2,4,6,7,8,9,10,11].随着并发访问量增大,系统的性能极大受限于在线编译系统.例如,一类全国类的竞赛就因为受到在线编译系统性能的影响,导致比赛时许多参与者的代码不能及时提交,影响成绩.
语言类编译器,根据编译结果是中间码文件还是机器可直接执行的最终机器码文件,依赖于平台或与平台无关.C/C++语言依赖于平台,编译成机器码文件,因而在不同的操作系统上,需要用不同的编译器;java语言由于编译成中间字节代码,因而其编译产生的目标文件与平台无关,故可用java API提供的编译模块.
在这样的在线编译系统中,由于其源文件由Web后台提供,而且其编译结果也需要通过Web反馈给前台,因而与Web应用系统关联密切.所以一种最方便的做法就是将在线编译系统与Web应用服务器部署在同一台机器上,或者让在线编译系统访问与Web应用系统相同的数据库.这种做法降低了在线编译系统的可扩展性,因而,对于C10K问题其性能会显著下降.
我们通过将在线编译系统与Web应用系统中间耦合环节用消息队列取代,使Web应用系统与在线编译系统变成一种松耦合结构,因而构建出一种可扩展的在线编译系统.
2系统模块
2.1系统框架
构建可扩展的在线编译系统的关键是将Web应用系统与在线编译系统的紧耦合结构变成一种松耦合结构.我们采用消息队列作为Web应用系统与在线编译系统交互的中间组件.
系统框架如下所示:
图1 系统构架图
图1所示的构架中,客户端将代码粘贴到文本框,提交到Web服务器后,后者指明语言类型,并将该编程题的输入数据及结果文件数据一起组成一个编译请求,发送到消息队列,编译服务程序通过消息队列获取一份编译请求,进行编译或运行,将结果返回.
2.2前端页面
前端页面除了为用户提供编辑代码的界面外,还有一个作用:等待接收编译服务返回的编译或运行的结果.通过用一个消息队列的异步模块,页面通过javascript启动消息队列异步接收模块.从而,使Web服务器对每个Web请求从同步处理变成异步处理,减轻Web服务器的负担.
2.3Web服务器
Web服务器除了直接处理前台的Web请求外,还将前台提交的代码的编程语言类型以及代码所属题目的测试数据及答案数据等一起组成一个编译请求,用Java消息服务接口(JMS)发送到消息队列.前台提交的代码其结果直接由编译服务通过消息队列传递给客户.
2.4消息队列
消息队列在整个系统中起着一个中间件的作用,一端连接Web服务器,另一端连接编译服务.它本身并不需要很多编程工作,只需要将其启动运行即可.
2.5编译服务器
编译服务器主要完成用户提交代码的编译或运行,如果编译出现错误,则直接将编译错误作为结果,发送到消息队列,由客户接收;如果无编译错误,则用Web服务器提供的测试数据运行程序,将得到的结果与Web服务器提供的结果文件进行比较.并将运行结果通过消息队列返回给客户.
编译服务器从消息队列接收或向消息队列发送消息,运用消息队列activemq提供的C++编程接口.
3关键技术
3.1JMS接口
为在Web服务器中使用activemq消息队列,需要一个activemq-client jar包,把这个jar包加入lib目录后,就可使用JMS接口发送消息到activemq消息队列了.
当收到客户提供的代码时,调用JMS接口将代码放进消息队列:
新建一个连接工厂;
创建一个连接;
创建一个连接上的会话;
在会话上创建一个主题;
设置代码语言属性;
将代码作为消息发送到消息队列.
3.2消息队列通信接口
先下载activemq-cpp源程序包,接着下载其依赖包源程序包:cppunit,apr,apr-util,apr-iconv;然后再编译四个依赖包,分别得到cppunit.dll,apr.dll,apr-util.dll,apr-iconv,最后再编译activemq-cpp,得activemq-cpp.dll.
在编译服务程序入口端,通过调用activemq-cpp接口从activemq消息队列中接收提交的源程序:
获取CMS连接工厂;
创建一个连接;
创建一个连接上的会话;
在会话上创建一个主题;
创建一个消息接收者;
重载onMessage()方法.
在onMessage()中接收提供的代码.
在编译服务程序出口端,将相关编译错误消息或运行结果信息作为一个消息队列到activemq消息队列:
获取CMS连接工厂;
创建一个连接;
创建一个连接上的会话;
在会话上创建一个主题;
创建一个消息发送者;
设置消息编号属性;
发送消息到消息队列.
在用activemq-c++编程接口从消息队列接收或向其发送消息时,需要解决字符编码问题.在Web服务器端,由于采用Java开发,字符编码用UTF-8,在编译服务器一端,由于要以windows服务的形式运行,采用的编译继承windows默认编码.由于两端编码不同,导致通过消息队列收发的消息不正确.因此,我们提供了一个编码接口.
3.3编译服务
在编译服务中,通过消息队列接口获取待编译代码及测试数据和测试结果,然后根据代码语言类型分别调用相应语言的编译服务.
Java语言类的编译服务不是直接调用javac进行编译,而是通过调用java动态编译类进行编译,同时获取编译可能的错误信息.
C/C++语言类的编译服务只能直接调用不同平台下的编译器进行编译,例如,windows平台下调用cl,linux平台下调用gcc/g++进行编译,通过分析其输出结果判断编译有无错误.
在编译有错误时,停止对程序的运行,并将错误消息通过消息队列接口发送到消息队列.
当编译正确时,对于所运行的用户程序必须限制其资源和运行时间.对于java类程序,可通过动态编译运行工具的支持对所运行的java程序设置内存及运行时间的限制.
对于C/C++类编译器生成的机器码程序,由于无相关的动态编译运行机制,必须通过system方法调用这些机器码程序运行,因而比较难于控制.因此,在编译服务程序中为每个编译服务创建一个新进程,并将每个新创建的进程的启动时间记录到一个哈希表中,以进程句柄为键值,设置一个计时器,计时器中断时间为1秒,在WM_TIMER事件中用当前系统时间减去哈希表中所记录每个进程的启动时间,如果超时,则调用TerminateProcess中止该进程,并通过activemq-cpp消息队列接口向该用户发送超时消息.
为监控C/C++程序使用内存情况,可用SetTimer设置第二个计时器,并将每个新建进程当前所用内存记录到第二个哈希表,也以进程句柄为键值,在WM_TIMER事件中用其计时器ID来区分第一个与第二个,用Get Process Memory Info函数获取当前运行进程占用的内存,每当某个进程所用内存超过上限,则用Terminate Process终止此进程,并将内存超限的错误消息通过消息队列接口发送到消息队列.
4测试环境与结果
测试环境:局域网带宽100 Mbps,Web服务器由一台PC机承担,编译服务放在另一台PC机上,windows平台.PC机2G内存,Intel i3 4核CPU,客户机也由PC机承担.
测试过程:分别由5台PC机作C、C++和java在线编程练习,检验其响应时间和结果.其中一个C程序是一个无限循环程序,另一个C程序则分配10M的内存,导致内存超限(内存限制设置为2M),计时限制为1秒.对每个测试程序,都提交两遍:一遍是正确的,另一遍是错误的.
测试代码提交与结果返回:
图2 代码提交与编译结果返回示意图
左边是代码提交,右边是由编译服务器返回的编译运行结果.
测试结果如表1.
表1 测试结果
测试结果说明对于C/C++程序运行的时间控制和使用内存限制正常发挥作用,对于java程序运行的时间限制和内存限制也是正常的;整个程序流程从前台到编译服务程序再返回到前台是完全正确的.
我们再将编译服务程序部署到一台新的机器上,让测试机器提交测试代码,结果部署的两套编译服务程序都正常工作.这说明我们的基于消息队列的在线编译系统具有可扩展性.
5结束语
在线编译系统是程序设计类网上课程或竞赛系统的一个关键模块,大多的这类系统都受限于部署在线编译系统的机器的性能,所能支持的并发用户数有限.我们的系统由于与Web服务器的耦合被消息队列所间隔,因而可将在线编译系统部署在其他机器上,而且部署机器数不会受到系统因素的限制,因而具有可扩展性.系统存在的一个问题是,编译服务程序运行的结果直接返回给用户,而未经过Web服务器的评判记分,这是一个有待改进的地方.但编译服务程序给出的结果信息还是明确的:提交的代码是正确还是错误的.
参考文献:
[1]田地.支持移动端的C语言在线编译系统的设计与实现[J].信息通信,2015(1):113-115.
[2]尤枫,史晟辉,赵瑞莲.编译程序在线评测系统的实现[J].实验室研究与探索,2010(12):69-73.
[3]张巍.在线编译教学系统在C/C++课程中的应用与研究[J].才智,2009(11):69-70.
[4]刘晓君.基于Web的虚拟教学系统设计与实现[D].成都:电子科技大学,2012:31-43.
[5]蒋燕敏.自动判题算法及网络考试平台研究[D].杭州:浙江工业大学,2014,硕士论文.
[6]汪松松.基于在线服务模式的程序编译平台的研究[J].科技信息,2011(31):461-462.
[7]翟红英,王波.基于C#.NET的在线编译方法的应用与研究[J].计算机光盘软件与应用,2013(7):97-98.
[8]梅刚,林龄,潘峰.基于Web的在线编译环境设计[J].计算机时代,2015(5):29-31.
[9]汪松松.基于在线服务模式的程序编译平台的研究.2011(41):462+461.
[10]张恒升,陈翰博,王伟,等.基于net和Ajax的在线编译器网络平台开发[J].价值工程,2010(5):152-153.
[11]陈元静.基于J2EE/SSH在线代码评测系统的设计与实现[D].成都:电子科技大学,2013:23-32.
[12]昝镇.面向MOOC的程序设计辅助教学系统[D].西安:西北大学,2014:32-45.
[13]熊茜,雷亮,许莎,等.基于在线判题系统的C语言实验教学改革[J].重庆学院学报(社会科学版),2015(10):67-69.
[14]龙虎,张小梅,唐林海.大数据背景下智慧教育云平台的构建研究[J].电脑知识与技术,2015(20):109-111.
The Online Compiling System Based on Message Queue
YU Shu-chun,YE Qing,WANG Peng
(CollegeofComputerScienceandEngineering,HuaihuaUniversity,Huaihua,Hunan418008)
Abstract:The online compiling system is the key component of the programming online course exercise or programming design contest,its performance directly affects the concurrent user number of the web site.The online compiling system based on the message queue make a loose coupling structure between the Web server and the online compiling service,so it can support more concurrent user by deploying more than one online compiling system.Paper proposed using the message queue as the middle component between the Web server and the online compiling system,analyzed the interactive interface technique,such as JMS and activemq-cpp,and studied how to limit the run time and the used memory of the C/C++ program.Test shows that this loose coupling structure is flexible.
Key words:message queue;JMS;activemq;online compiling
收稿日期:2015-11-29
基金项目:湖南省教育厅科研资助项目(13C714);怀化学院重点学科建设项目;怀化学院大学生创新项目.
作者简介:于述春,1965年生,男,讲师,研究方向:计算机网络、云计算、计算机视觉.
中图分类号:TP311
文献标识码:A
文章编号:1671-9743(2016)05-0056-04