Serverless 实践系列(三):突破传统 OJ 瓶颈,“判题姬”接入云函数
随着时代的发展,OJ 已经真正成为测评工具,其作用不再局限为 ACM 备战,还有老师检测学生能力、学生入学考试、能力评测(例如 ZJU 的 PAT)、找工作刷题和面试(例如牛客)等,而目前 OJ 的开源框架也越来越多,但是很多 OJ 都是基于 HUSTOJ 进行定制或者二次开发。
无论是什么方法,在 OJ 的众多问题中,有一个就是:性能问题。说实话,我在一些 OJ 群里,经常会看到有人问:1 核 1G 的机器,可以同时判多少题目?可以有多少人同时用?如果比赛,大约有多少人需要多高性能的机器?那么 ” 判题姬 ” 是否只能存在传统的宿主机中,能否通过其他方式焕发新的生命力?
有一种方法,就是和现有的云函数进行结合。
简单思路
通过云函数实现在线编程的思路基本有两个:
- 每个用户的代码建立一个函数,用后删除;
- 每个语言建立一个函数,用户传递代码,每次执行;
这两种方法,第一种无疑是简单的,但是目前对于很多云函数服务商来说,函数数量有一定限制,而且每次执行这个操作相对比较繁琐。
所以,本文采用第二种策略,建立一个函数,每次执行,用户传入代码,系统执行,返回结果。
基本实现
代码写入系统:
复制代码
defWriteCode(code): try: withopen("/tmp/mytest.py","w")asf: f.write(code) returnTrue exceptExceptionase: print(e) returnFalse
执行代码:
复制代码
def RunCode(input_data=None): child = subprocess.Popen("python /tmp/mytest.py",stdin=input_data,stdout=subprocess.PIPE,stderr=subprocess.PIPE,close_fds=True,shell=True) error= child.stderr.read() output = child.stdout.read() return error, output
代码和用例处理逻辑:
复制代码
defmain_handler(event, context): ifWriteCode(event["code"]): try: temp_list= [] foreveinevent["input"]: result = RunCode() temp_list.append({"error":result[0].decode("utf-8"),"result": result[1].decode("utf-8"),"exception":""}) returnjson.dumps(temp_list) except Exceptionase: returnjson.dumps({"error":"","result":"","exception":str(e)})
用户在传入数据的时候,需要注意事件为:
复制代码
{ "code":"print('hello')", "input": ["111","22222"] }
这样就可以在每次请求的时候把代码传入(code),每个测试用例的 input 就是 input 内容。
本题输出结果:
此时,就实现了 Python 判题机的基本功能,此时通过腾讯云云 API:
( https://cloud.tencent.com/document/api/583/17243 )实现参数传入,通过
Explorer( https://console.cloud.tencent.com/api/explorer?Product=scf&Version=2018-04-16&Action=Invoke&SignVersion= )
进行代码撰写,直接接入自己的 OJ 就可以了。
One More Thing
虽然这是一个简单的代码执行工具,但是实际上这个小工具可以在很多地方有着额外的应用。本文我只是再次只是抛砖引玉,例如我们做了一个 OJ,如果在本地跑代码可能性能和安全性都会受到挑战,那么此时,放入腾讯云云函数中,就会简单、安全、便捷的多,最主要的是腾讯云的函数调用免费额度很高。
此外,如果临时举办比赛,也不用费心费力扩容缩容,只要有云函数,后端的主要压力,都传给 Serverless 搞定,这也算是发挥了云函数的一个优势和特性。
那么,除了在 OJ 中使用的用途,它还有啥用?简单举两个例子:
- Anycodes、Codepad 这些在线编程网站,之前很多人就问是如何实现的,试想一下,通过这个策略,是不是很好实现了在线编程?确切说,只需要一个前端,就可以实现在线写代码的一个网页。
- 菜鸟教程这些网站,可以看代码然后点击运行,很炫酷的功能,很多小伙伴也想往自己博客增加一个类似的功能,也可以基于这个方法来实现。
作者介绍:
刘宇,腾讯云 Serverless 团队后台研发工程师。毕业于浙江大学,先后参与腾讯云云函数产品研发、自动扩缩容、CLI 等模块建设以及社区相关工作。本文转载自微信公众号 ServerlessCloudNative(ID:ServerlessGo)