作者 | 计缘
起源 | Serverless 公众号
说起 Serverless 这个词,我想大家应该都不生疏,那么 Serverless 这个词到底是什么意思?Serverless 到底能解决什么问题?可能很多敌人还没有粗浅的领会和体感,这篇文章我就和大家一起聊聊 Serverless。
什么是 Serverless
咱们先将 Serverless 这个词拆开来看。Server,大家都晓得是服务器的意思,阐明 Serverless 解决的问题范畴在服务端。Less,大家必定也晓得它的意思是较少的。那么 Serverless 连起来,再稍加润饰,那就是较少的关怀服务器的意思。
Serverfull 时代
咱们都晓得,在研发侧都会有研发人员和运维人员两个角色,要开发一个新零碎的时候,研发人员依据产品经理的PRD开始写代码开发性能,当性能开发、测试完之后,要公布到服务器。这个时候开始由运维人员布局服务器规格、服务器数量、每个服务部署的节点数量、服务器的扩缩容策略和机制、公布服务过程、服务优雅高低线机制等等。这种模式是研发和运维隔离,服务端运维都由专门的运维人员解决,而且很多时候是靠纯人力解决,也就是 Serverfull 时代。
DevOps 时代
互联网公司里最辛苦的是谁?我置信大多数都是运维同学。白天做各种网络布局、环境规划、数据库布局等等,早晨熬夜公布新版本,做上线保障,而且很多事件是重复性的工作。而后缓缓就有了赋能研发这样的声音,运维同学帮忙研发同学做一套运维控制台,能够让研发同学在运维管制台上自行公布服务、查看日志、查问数据。这样一来,运维同学次要保护这套运维控制台零碎,并且不断完善性能,轻松了不少。这就是研发兼运维的 DevOps 时代。
Serverless 时代
慢慢的,研发同学和运维同学的关注点都在运维控制台了,运维控制台的性能越来越弱小,比方依据运维侧的需要减少了主动弹性扩缩、性能监控的性能,依据研发侧的需要减少了自动化公布的流水线性能。因为有了这套零碎,代码品质检测、单元测试、打包编译、部署、集成测试、灰度公布、弹性扩缩、性能监控、利用防护这一系列服务端的工作基本上不须要人工参加解决了。这就是 NoOps,Serverless 时代。
Serverless在编程教育中的利用
2020 年注定是不平庸的一年,疫情期间,多少家企业如割韭菜般倒下,又有多少家企业如雨后春笋般茁壮成长,比方在线教育行业。
没错,在线教育行业是这次疫情的最大受益者,在在线教育在这个行业里,有一个细分市场是在线编程教育,尤其是少儿编程教育和面向非专业人士的编程教育,比方编程猫、斑马 AI、小象学院等。这些企业的在线编程零碎都有一些独特的特点和诉求:
屏幕一侧写代码,执行代码,另一侧显示运行后果。
依据题目编写的代码都是代码块,每道题的代码量不会很大。
运行代码的速度要快。
反对多种编程语言。
能撑持不可预计的流量洪峰冲击。
例如小象学院的编程课界面:
联合上述这些特点和诉求,不难看出,构建这样一套在线编程零碎的外围在于有一个反对多种编程语言的、强壮高可用的代码运行环境。
那么咱们先来看看传统的实现架构:
从 High Level 的架构来看,前端只须要将代码片段和编程语言的标识传给 Server 端即可,而后期待响应展现后果。所以整个 Server 端要负责对不同语言的代码进行分类、预处理而后传给不同编程语言的 Runtime。这种架构有以下几个比拟外围的问题。
工作量大,灵活性差
首先是研发和运维工作量的问题,当市场有新的需要,或者洞察到新业务模式时须要减少编程语言,此时研发侧须要减少编程代码分类和预处理的逻辑,另外须要构建对应编程语言的 Runtime。在运维侧须要布局撑持新语言的服务器规格以及数量,还有整体的 CICD 流程等。所以反对新的编程语言这个需要要落地,须要研发、运维破费不少的工夫来实现,再加上黑/白盒测试和 CICD 流程测试的工夫,对市场需求的撑持不能疾速的响应,灵活性绝对较差。
高可用本人兜底
其次整个在线编程零碎的稳定性是重中之重。所以所有 Server 端服务的高可用架构都须要本人搭建,用以保障流量顶峰场景和稳态场景下的零碎稳固。高可用一方面是代码逻辑编写的是否优雅和欠缺,另一方面是部署服务的集群,无论是 ECS 集群还是 K8s 集群,都须要研发和运维同学一起布局,那么对于对编程语言进行分类和预处理的服务来讲,尚能给定一个节点数,然而对于不同语言的 Runtime 服务来讲,市场需求随时会变,所以不好具体掂量每个服务的节点数。另外很重要的一点是所以服务的扩容,缩容机制都须要运维同学来实时手动操作,即使是通过脚本实现自动化,那么 ECS 弹起的速度也是远达不到业务预期的。
老本管制粒度粗
再次是整个 IaaS 资源的老本管制,咱们都晓得这种在线教育是有显著的流量潮汐的,比方上午 10 点到 12 点,下午 3 点到 5 点,早晨 8 点到 10 点这几个时段是流量比拟大的时候,其余工夫端流量比拟小,而且夜晚更是没什么流量。所以在这种状况下,传统的部署架构无奈做到IaaS资源和流量的贴合。举个例子,退出为了应答流量顶峰期间,须要 20 台 ECS 搭建集群来承载流量冲击,此时每台 ECS 的资源使用率可能在 70% 以上,利用率较高,然而在流量小的时候和夜晚,每台 ECS 的资源使用率可能就是百分之十几甚至更低,这就是一种资源节约。
Serverless 架构
那么咱们来看看如何应用 Serverless 架构来实现同样的性能,并且解决上述几个问题。在抉择 Serverless 产品时,在国内自然而然优先想到的就是阿里云的产品。阿里云有两款 Serverless 架构的产品 Serverless 利用引擎和函数计算,这里咱们应用函数计算来实现编程教育的场景。
函数计算(Function Compute)是事件驱动的全托管计算服务,简称 FC。应用函数计算,咱们无需洽购与治理服务器等基础设施,只需编写并上传代码。函数计算为您筹备好计算资源,弹性地、牢靠地运行工作,并提供日志查问、性能监控和报警等性能。
这里不对 FC 的含意做过多赘述,只举一个例子。FC 中有两个概念,一个是服务,一个是函数。一个服务蕴含多个函数:
这里拿 Java 微服务架构来对应,能够了解为,FC 中的服务是 Java 中的一个类,FC 中的函数是 Java 类中的一个办法:
然而 Java 类中的办法诚然只能是 Java 代码,而 FC 中的函数能够设置不同语言的 Runtime 来运行不同的编程语言:
这个构造了解分明之后,咱们来看看如何调用 FC 的函数,这里会引出一个触发器的概念。咱们最常应用的 HTTP 申请协定其实就是一种类型的触发器,在 FC 里称为 HTTP 触发器,除了 HTTP 触发器以外,还提供了 OSS(对象存储)触发器、SLS(日志服务)触发器、定时触发器、MNS 触发器、CDN 触发器等。
从上图能够大略了解,咱们能够通过多种路径调用 FC 中的函数。举例两个场景,比方每当我在指定的 OSS Bucket 的某个目录下上传一张图片后,就能够触发 FC 中的函数,函数的逻辑是将刚刚上传的图片下载下来,而后对图片做解决,而后再上传回 OSS。再比方向 MNS 的某个队列发送一条音讯,而后触发 FC 中的函数来解决针对这条音讯的逻辑。
最初咱们再来看看 FC 的高可用。每一个函数在运行代码时底层必定还是IaaS资源,但咱们只须要给每个函数设置运行代码时须要的内存数即可,最小 128M,最大 3G,对使用者而言,不须要思考多少核数,也不须要晓得代码运行在什么样的服务器上,不须要关怀启动了多少个函数实例,也不须要关怀弹性扩缩的问题等,这些都由 FC 来解决。
从上图能够看到,高可用有两种策略:
给函数设置并发实例数,如果设置为 3,那么有三个申请进来时,该函数只启一个实例,然而会启三个线程来运行逻辑。线程数达到下限后,会再拉起一个函数实例。
大家看到这里,可能曾经大略对基于 FC 实现在线编程教育零碎的架构有了一个大略的轮廓。
上图是基于 FC 实现的在线编程教育零碎的架构图,在这个架构下来看看上述那三个外围问题怎么解:
- 工作量和灵活性:咱们只须要关注在如何执行代码的业务逻辑上,如果要加新语言,只须要创立一个对应语言 Runtime 的 FC 函数即可。
- 高可用:多线程运行业务逻辑和多实例运行业务逻辑两层高可用保障,并且函数实例的扩缩齐全都是 FC 主动解决,不须要研发和运维同学做任何配置。
- 老本优化:当没有申请的时候,函数实例是不会被拉起的,此时也不会计费,所以在流量低谷期或者夜间时,整个 FC 的老本耗费是非常低的。能够做到函数实例个数、计费粒度和流量完满的贴合。
Python编程语言示例
上面以运行 Python 代码为例来看看如何用 FC 实现 Python 在线编程 Demo。
创立服务和函数
关上函数计算(FC)控制台,抉择对应的 Region,抉择左侧服务/函数,而后新建服务:https://fc.console.aliyun.com/fc/overview/cn-hangzhou
输入服务名称,创立服务。
进入新创建的服务,而后创立函数,抉择 HTTP 函数,即可配置 HTTP 触发器的函数:
设置函数的各个参数:
几个须要的留神的参数这里做以阐明:
- 运行环境:这个很好了解,这里抉择P ython3
- 函数实例类型:这里有弹性实例和性能实例两种,前者最大反对2C3G规格的实例,后者反对更大的规格,最大到8C16G。
- 函数入口:具体参见文档 - HTTP 触发器认证形式:anonymous 为不须要鉴权,function 是须要鉴权的。https://help.aliyun.com/document_detail/74756.html?spm=a2c4g.11186623.6.572.195359cdselnzR
代码解析
函数创立好,进入函数,能够看到概述、代码执行、触发器、日志查问等页签,咱们先看触发器,会看到这个函数主动创立了一个 HTTP 触发器,有调用该函数对应的 HTTP 门路:
而后咱们抉择代码执行,间接在线写入咱们的代码:
具体代码如下:
-- coding: utf-8 --import loggingimport urllib.parseimport timeimport subprocessdef handler(environ, start_response):context = environ['fc.context']request_uri = environ['fc.request_uri']for k, v in environ.items():if k.startswith('HTTP_'):passtry:request_body_size = int(environ.get('CONTENT_LENGTH', 0))except (ValueError):request_body_size = 0# 获取用户传入的coderequest_body = environ['wsgi.input'].read(request_body_size)codeStr = urllib.parse.unquote(request_body.decode("GBK"))# 因为body里的对象里有code和input两个属性,这里别离获取用户code和用户输出codeArr = codeStr.split('&')code = codeArr[0][5:]inputStr = codeArr[1][6:]# 将用户code保留为py文件,放/tmp目录下,以工夫戳为文件名fileName = '/tmp/' + str(int(time.time())) + '.py'f = open(fileName, "w")# 这里预置引入了time库f.write('import time \r\n')f = open(fileName, "a")f.write(code)f.close()# 创立子过程,执行方才保留的用户code py文件p = subprocess.Popen("python " + fileName, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, encoding='utf-8')# 通过规范输出传入用户的input输出if inputStr != '' :p.stdin.write(inputStr + "\n")p.stdin.flush()# 通过规范输入获取代码执行后果r = p.stdout.read()status = '200 OK'response_headers = [('Content-type', 'text/plain')]start_response(status, response_headers)return [r.encode('UTF-8')]
整个代码思路如下:
- 从前端传入代码片段,格局是字符串。
- 在 FC 函数中获取到传入的代码字符串,截取 code 内容和 input 的内容。因为这里简略实现了 Python 中 input 交互的能力。
- 将代码保留为一个 Python 文件,以工夫戳为文件名,保留在 FC 函数的 /tmp 目录下。(每个 FC 函数都有独立的 /tmp 目录,能够寄存临时文件)
- 而后在文件中追加了引入 time 库的代码,应答 sleep 这种交互场景。
- 通过 subprocess 创立子过程,以 Shell 的形式通过 Python 命令执行保留在 /tmp 目录下的 Python 文件。如果有用户输出的信息,则通过规范输入输出写入子过程。
- 最初读取执行后果返回给前端。
前端代码
前端我应用 VUE 写了简略的页面,这里解析两个简略的办法:
页面加载时初始化 HTTP 申请对象,调用的 HTTP 门路就是刚才函数的 HTTP 触发器的门路。
这个办法就是调用 FC 中的 PythonRuntime 函数,将前端页面的代码片段传给该函数。这里解决 input 交互的思路是,扫描整个代码片段,以蕴含 input 代码为标识将整个代码段分成多段。没有蕴含 input 代码的间接送给 FC 函数执行,蕴含 input 代码的,申请用户的输出,而后代码片段带着用户输出的信息一起送给 FC 函数执行。
演示如下:
结束语
这篇文章给大家介绍了 Serverless,阿里云的 Serverless 产品函数计算(FC)以及基于函数计算(FC)实现的在线编程零碎的 Demo。大家应该有所体感,基于函数计算(FC)实现在线编程零碎时,研发同学只须要专一在如何执行由前端传入的代码即可,整个 Server 端的各个环节都不须要研发同学和运维同学去关怀,根本体现了 Serverless 的精华。
基于 Serverless 还有很多其余的利用场景,之后我会一一分享给大家,咱们不见不散!