用手机写代码:基于Serverless的在线编程能力探索(上)

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 随着计算机科学与技术的发展,越来越多的人开始接触编程,也有越来越多的在线编程平台诞生。以Python语言的在线编程平台为例,关于Python语言的在线编程平台大致分为两类,一类是OJ类型的,即在线评测的编程平台,另一类则是学习、工具类的在线编程平台,例如Anycodes在线编程等网站。

前言

随着计算机科学与技术的发展,越来越多的人开始接触编程,也有越来越多的在线编程平台诞生。以Python语言的在线编程平台为例,关于Python语言的在线编程平台大致分为两类,一类是OJ类型的,即在线评测的编程平台,另一类则是学习、工具类的在线编程平台,例如Anycodes在线编程等网站。

但是,无论是那种类型,其背后的核心模块“代码执行器”/“判题机”等,都是值得被关注的。一方面,这类网站通常情况下都需要比要严格的“安全考虑”,例如程序会不会有恶意代码,出现死循环、破坏计算机系统等,程序是否需要隔离运行,运行时是否会获取到其他人提交的代码等;另一方面,这类平台通常情况下都会对资源消耗比较大,尤其是比赛来临时,更是需要突然间对相关机器进行扩容,必要时需要大规模集群来进行应对。同时这类网站通常情况下也都有一个比较大的特点,那就是触发式,即每个代码执行前后实际上并没有非常紧密的前后文关系等。

综合上面的问题和特点,结合Serverless架构,本文将会通过“Serverless角度”,实现简单的Python语言的在线编程能力,并对其进行进一步探索。


简单的在线代码执行器

基本流程

这一部分将会Python语言实现一个简单的在线代码执行工具,该工具拥有以下特点:

  • 可以执行Python代码
  • 支持标准输入
  • 可以返回标准输出和标准错误

该简单工具的整个过程包括:

代码实现

其中执行代码部分,我们可以通过一些常见的Python依赖库,例如subprocess来进行实现:

child = subprocess.Popen("python %s" % (fileName),

                        stdin=subprocess.PIPE,

                        stdout=subprocess.PIPE,

                        stderr=subprocess.STDOUT,

                        shell=True)

output = child.communicate(input=input_data.encode("utf-8"))

print(output)

在函数计算中(无论阿里云函数计算还是腾讯云云函数),通常情况下,再不进行硬盘挂载的前提下,只有/tmp/目录是有可写入权限的,所以函数计算部分,可以将代码写入临时目录/tmp/,并进行代码运行,获得结果:

# -*- coding: utf-8 -*-


import os

import json

import uuid

import random

import subprocess


# 随机字符串

randomStr = lambda num=5: "".join(random.sample('abcdefghijklmnopqrstuvwxyz', num))



# Response

class Response:

   def __init__(self, start_response, response, errorCode=None):

       self.start = start_response

       responseBody = {

           'Error': {"Code": errorCode, "Message": response},

       } if errorCode else {

           'Response': response

       }

       # 默认增加uuid,便于后期定位

       responseBody['ResponseId'] = str(uuid.uuid1())

       print("Response: ", json.dumps(responseBody))

       self.response = json.dumps(responseBody)


   def __iter__(self):

       status = '200'

       response_headers = [('Content-type', 'application/json; charset=UTF-8')]

       self.start(status, response_headers)

       yield self.response.encode("utf-8")



def WriteCode(code, fileName):

   try:

       with open(fileName, "w") as f:

           f.write(code)

       return True

   except Exception as e:

       print(e)

       return False



def RunCode(fileName, input_data=""):

   child = subprocess.Popen("python %s" % (fileName),

                            stdin=subprocess.PIPE,

                            stdout=subprocess.PIPE,

                            stderr=subprocess.STDOUT,

                            shell=True)

   output = child.communicate(input=input_data.encode("utf-8"))

   print(output)

   return output[0].decode("utf-8")



def handler(environ, start_response):

   try:

       request_body_size = int(environ.get('CONTENT_LENGTH', 0))

   except (ValueError):

       request_body_size = 0

   requestBody = json.loads(environ['wsgi.input'].read(request_body_size).decode("utf-8"))


   code = requestBody.get("code", None)

   inputData = requestBody.get("input", "")

   fileName = "/tmp/" + randomStr(5)


   if code and WriteCode(code, fileName):

       output = RunCode(fileName, inputData)

       responseData = output

   else:

       responseData = "Error"


   print(responseData)


   return Response(start_response, {"result": responseData})


部署上线

当代码编写完成,可以直接通过Serverless-Devs工具进行项目部署,首先编写template.yaml文件:

ServerlessBookRunCodeDemo:

 Component: fc

 Provider: alibaba

 Properties:

   Region: cn-beijing

   Service:

     Name: ServerlessBook

     Description: Serverless图书案例

     Log:

       Project: aliyun-fc-cn-beijing-9bd4a65b-c9d1-529d-9ce0-c91adfb823ab

       LogStore: function-log

   Function:

     Name: serverless_run_code_ordinary

     Description: 简单版代码在线执行器

     CodeUri: ./

     Handler: index.handler

     MemorySize: 128

     Runtime: python3

     Timeout: 5

     Triggers:

       - Name: RunCodeOrdinary

         Type: HTTP

         Parameters:

           AuthType: ANONYMOUS

           Methods:

             - GET

             - POST

             - PUT

           Domains:

             - Domain: Auto

完成编写之后,可以通过:

s deploy

进行项目部署:

完成项目部署之后,可以通过:

s logs -t

对日志系统进行监听,当函数被触发时,可以看到我们的一些日志内容。

接口测试

接下来,可以通过PostMan进行接口测试,以Python语言的输出语句为例:

print('HELLO WORLD')

测试结果:

可以看到,系统是可以正常输出我们的预期结果:HELLO WORLD,当我们将该部分代码进行破坏:

print('HELLO WORLD)

再次执行,可以看到错误结果:

当我们将带有输入内容的代码传入:

tempInput = input('please input: ')

print('Output: ', tempInput)

并输入“serverless devs”,可以看到:

至此我们完成了一个非常简单的在线代码执行的接口。针对这个接口,是有蛮大的优化空间的:

  • 超时时间的处理
  • 代码执行完成,可以进行清理

当然,通过这个接口也可以看到这样一个问题:那就是代码执行过程中是阻塞的,我们没办法进行持续性的输入,就算是想要输入内容也是需要将代码和输入内容一并发送到服务端。这种模式和目前市面上常见的OJ模式很类似。所以,针对上述的简单的在线代码执行器而言,是可以进行部分完善与OJ系统进行结合使用。

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
3月前
|
消息中间件 JavaScript 中间件
函数计算产品使用问题之WebIDE编写的Node.js代码是否会自动进行打包部署
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
3月前
|
存储 运维 Serverless
函数计算产品使用问题之如何解决代码需要多个gpu的问题
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
25天前
|
Serverless 数据安全/隐私保护 前端开发
大模型代码能力体验报告之贪吃蛇小游戏《一》:Claude.ai篇 - 生成、预览和快速部署的serverless一条龙
本文介绍了通过Claude.ai生成并优化Web版贪吃蛇游戏的过程,展示了其强大的代码生成功能及用户友好的界面设计。从初始版本的快速生成到根据用户反馈调整游戏速度,再到提供多种实用工具如文件管理、版本控制和一键部署,Claude.ai不仅是一个代码助手,更像是一个全面的serverless开发平台。文中还呼吁国内厂商关注此类技术的发展。
|
1月前
|
JavaScript 前端开发
电话号码正则表达式 代码 javascript+html,JS正则表达式判断11位手机号码
电话号码正则表达式 代码 javascript+html,JS正则表达式判断11位手机号码
99 1
|
3月前
|
存储 运维 Serverless
函数计算产品使用问题之代码上传记录如何查看
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
4月前
|
缓存 运维 Java
函数计算产品使用问题之如何在函数代码的根目录中执行命令
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
2月前
|
人工智能 自然语言处理 Serverless
阿里云函数计算 x NVIDIA 加速企业 AI 应用落地
阿里云函数计算与 NVIDIA TensorRT/TensorRT-LLM 展开合作,通过结合阿里云的无缝计算体验和 NVIDIA 的高性能推理库,开发者能够以更低的成本、更高的效率完成复杂的 AI 任务,加速技术落地和应用创新。
149 13
|
3月前
|
Serverless API 异构计算
函数计算产品使用问题之修改SD模版应用的运行环境
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
3月前
|
运维 Serverless 网络安全
函数计算产品使用问题之通过仓库导入应用时无法配置域名外网访问,该如何排查
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
16天前
|
运维 Serverless 数据处理
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
51 1

热门文章

最新文章

相关产品

  • 函数计算