写点什么

Serverless 实践系列(三):突破传统 OJ 瓶颈,“判题姬”接入云函数

  • 2019-08-16
  • 本文字数:1739 字

    阅读完需:约 6 分钟

Serverless实践系列(三):突破传统OJ瓶颈,“判题姬”接入云函数

随着时代的发展,OJ 已经真正成为测评工具,其作用不再局限为 ACM 备战,还有老师检测学生能力、学生入学考试、能力评测(例如 ZJU 的 PAT)、找工作刷题和面试(例如牛客)等,而目前 OJ 的开源框架也越来越多,但是很多 OJ 都是基于 HUSTOJ 进行定制或者二次开发。


无论是什么方法,在 OJ 的众多问题中,有一个就是:性能问题。说实话,我在一些 OJ 群里,经常会看到有人问:1 核 1G 的机器,可以同时判多少题目?可以有多少人同时用?如果比赛,大约有多少人需要多高性能的机器?那么"判题姬"是否只能存在传统的宿主机中,能否通过其他方式焕发新的生命力?


有一种方法,就是和现有的云函数进行结合。

简单思路

通过云函数实现在线编程的思路基本有两个:


  • 每个用户的代码建立一个函数,用后删除;

  • 每个语言建立一个函数,用户传递代码,每次执行;


这两种方法,第一种无疑是简单的,但是目前对于很多云函数服务商来说,函数数量有一定限制,而且每次执行这个操作相对比较繁琐。


所以,本文采用第二种策略,建立一个函数,每次执行,用户传入代码,系统执行,返回结果。

基本实现

代码写入系统:


def WriteCode(code):    try:        with open("/tmp/mytest.py", "w") as f:            f.write(code)        return True    except Exception as e:        print(e)        return False
复制代码


执行代码:


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
复制代码


代码和用例处理逻辑:


def main_handler(event, context):    if WriteCode(event["code"]):        try:            temp_list = []            for eve in event["input"]:                result = RunCode()                temp_list.append({"error":result[0].decode("utf-8"),"result": result[1].decode("utf-8"), "exception":""})            return json.dumps(temp_list)        except Exception as e:            return json.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)


《Serverless 实践系列(一):如何通过 SCF 与自然语言处理为网站赋能》


《Serverless 实践系列(二):为 Python 云函数打包依赖》


《Serverless 实践系列(四):网站监控脚本的实现》


2019-08-16 15:3515166

评论

发布
暂无评论
发现更多内容

第六周作业

Vincent

极客时间 极客大学

对比 Redis 中 RDB 和 AOF 持久化

超超不会飞

【获奖名单公布】程序员摇身一变摄影师,属于技术人的摄影展示大赛

InfoQ写作社区官方

写作平台 征稿 热门活动

别闹,我用1个BTC居然买不了一个爱马仕包

猫Buboo

区块链+

Linux基金会唯一官方微服务培训课程免费学 | 快速构建稳定可靠的微服务应用

TARS基金会

开源 微服务 培训 Linux基金会 TARS

裳雨

GongTeng95

写作 写作平台

再深入一点|binlog和relay-log到底长啥样?

艾小仙

Java MySQL 数据库 架构设计

分库分表中间件的高可用实践

无毁的湖光

MySQL TCP 高可用 分库分表 高性能

最新:央行副行长详解数字人民币,信息量巨大!

CECBC

人民币 数字人民币

查找数组中最大值的5种方法!(动图演示)

王磊

Java 面试

Spring 5 中文解析数据存储篇-Spring框架的事物支持模型的优势

青年IT男

Spring5 数据存储

iPad Air把它大哥iPad Pro按在地上摩擦

徐说科技

flutter之踩坑的日子(2)

霜蓝手环

小程序flutter, 跨平台 Flutter Android Apk

数字资产会成为人类最大的资产

CECBC

数字资产 数字化时代 孙正义

java安全编码指南之:字符串和编码

程序那些事

安全编码指南 java安全编码 java安全编码指南

追光逐影:焦距与镜头语言

北风

创作 生活 摄影 光影 摄影征文

anyRTC语音开黑demo正式上线

anyRTC开发者

音视频 WebRTC 直播 RTC

互联网只改变了商业的一部分,区块链将从根本上重构商业

CECBC

区块链 去中心化 互联网金融

Golang领域模型-资源库

奔奔奔跑

微服务 领域驱动设计 DDD Go 语言

第六周学习总结

Vincent

极客时间 极客大学

111

不在调上

USDT支付系统开发技术方案,数字货币承兑商支付

13530558032

这是一个奇怪的因果关系

陈磊@Criss

摄影

MySQL数据库技术与应用:数据查询

华为云开发者联盟

MySQL 数据库 存储

血的教训!千万别在生产使用这些 redis 指令

楼下小黑哥

Java redis 生产事故

关于数据存储引擎结构,没有比这篇更详细的

华为云开发者联盟

数据库 nosql 存储

“度拉拉”升职记:中国语音助手的成长史

脑极体

数字货币交易所源码开发,区块链交易系统搭建服务商

13530558032

随想之UI+API

云杉

我是如何从0到1完成一个简单的中间件(1)

sinsy

Java 中间件

切片真的是引用类型嘛

Gopher指北

Go 语言

Serverless实践系列(三):突破传统OJ瓶颈,“判题姬”接入云函数_语言 & 开发_刘宇_InfoQ精选文章