Severless:云计算的下一个十年
Severless 国外发展较早,比较有代表性的是亚马逊和谷歌,而在国内,腾讯和阿里都将 Serverless 定义为集团战略型项目,不遗余力的推广和研发自己的 Serverless 技术。
Serverless 是一种后端架构技术,更准确的说,它应该是一种后端架构的概念或者思维。
Serverless 本身和前端没有任何关系,但它却是前端程序员最希望落地应用的技术,而很多后端程序员漠不关心甚至排斥,要搞清楚这一奇怪现象的原因,就要从后端架构的演进历史说起…
每一个 B/S 架构的互联网应用,都是由最基础的客户端和服务端构成的,客户端要呈现内容,就需要服务端提供服务。
最初,搭建一个服务器是非常繁琐的,我们需要购买一台电脑主机,然后找一个机房对机器进行托管,要将外观拍照,将各项硬件参数提交到备案中心进行备案,连接电源和网线,安装好操作系统,然后搭建好代码的运行环境,部署程序代码后,再将申请的域名和静态 IP 做好解析,就算是上线部署完毕了。
这样的服务器架构是单机版的单体架构,数据库、应用代码、HTTP 服务器等服务全都在一台你自己管理的服务器上运行,因为我们要接触物理机,所以,我们也把它称为 物理机时代。
在 物理机时代 不仅仅是上线部署非常繁琐的问题,在整个应用的运行中,还有各种各样的问题出现,比如磁道磨损的硬盘,机房的意外停电,老鼠咬断的网线等。
随着技术的不断发展,我们终于摆脱了 物理机时代,跨入 虚拟机时代。其中一个重要节点之一就是 2001 年 VMWare 带来的针对 x86 服务器的虚拟化产品,通过虚拟化技术,可以把一台物理机分割成多台虚拟机提供给用户使用,充分利用硬盘资源,而对于硬件设备的管理,统一由云厂商负责,对于开发者来说,就不用再买硬件了,直接在云平台购买虚拟机,比如 AWS 的 EC2、阿里云的 ECS、腾讯云的 CVM。
云服务器也真正的进入了大众的视野,开发者再也不用担心断电断网和硬件故障了。不过业务量的不断增长,用户越来越多,数据库每天都有几千万条数据写入,数据库性能很快就会达到瓶颈;除此之外,每天也有上百万图片存到磁盘,磁盘也快要耗尽了。
为了降低服务器负载,我们把数据库迁移到了云厂商提供的云数据库上,把图片存储迁移到对象存储:
这样一来,服务器就只负责处理用户的请求,把计算和存储分离开来,既降低了系统负载,也提升了数据安全性。并且单机应用升级为了集群应用,通过负载均衡,会把用户流量均匀分配到每台服务器上。
不过在服务器扩容的过程中,你还是会遇到一些麻烦。比如购买服务器后,都需要在上面初始化软件环境和配置,还需要保证所有服务器运行环境一致,这是个非常复杂还容易出错的工作。这对运维工程师也是一个非常大的挑战。
总的来说,虚拟机可以让你不用关心底层硬件,但是我们依然要为服务器集群的管理工作付出高昂的成本,如果有一项技术,能够在每次的服务器扩容时,让服务器的运行环境保持一致,那就太好了,于是容器技术应运而生。
2013 年 Docker 的发布,代表着容器技术替代了虚拟化技术,云计算进入容器时代。容器技术就是在虚拟化技术的基础上,把代码和运行环境打包在一期,这样,不论服务器的配置怎样,代码和运行环境均能保持一致性。
有了容器技术,你在服务器上部署的就不再是应用了,而是容器。当容器多了的时候,如何管理就成了一个问题,于是出现了容器编排技术,比如 2014 年 Google 开源的 Kubernetes,就是俗称额 K8S。
在目前的后端架构中,容器技术依然是主流的服务器架构技术,但是随着互联网应用的普及,我们需要面对各种各样的应用场景。
举个例子,每当大型购物节来临,我们的在线商城会面临巨大的流量洪峰,而在平时,流量显然要小很多,为了迎接购物节的流量洪峰,我们需要大量扩充服务器,服务器的扩充和大量容器的编排工作,也是一个不小的难题,如果我们对流量的压力预估不到位,还会有服务器宕机的风险,而在平时,如此多的服务器运行显然是在浪费资源增加成本。
那么,有没有一种技术,让我们只关心业务代码的功能实现,脱离服务器的管理呢?让我们不再为运行环境劳心伤神,不再为服务器的扩缩容半夜惊醒,当流量洪峰来临时,自动调配更多的服务器资源支撑;当流量低估时,自动释放服务器资源节约成本。这样美好的时代正在走来,它叫 Serverless。
简单总结一下:总管后端架构的发展史,其实就是 Serverless 的兴起史,每一个时代,都是对前一个时代基础架构的抽象。从物理机时代跨越到虚拟机时代,让哦我们不再关心硬件设备的管理,将一台真实的计算机抽象为相互隔离的多个虚拟机;从虚拟机时代到容器时代,让我们摆脱了运行环境和集群管理的繁杂工作,将虚拟机的运行环境抽象为容器;而 Serverless 的到来,让我们不再关心运行环境和服务器资源的调配。
Serverless 中有很多全新概念的引入,相对于具体的应用,Serverless 的相关理念更值得开发者探讨和学习。
技术圈对 Serverless 的定义在不断地调整和变化中,所以导致有不少开发者认为 FaaS(Funciton as a Service 函数即服务) 就是 Serverless,也有认为 PaaS(Platform as a Service 平台即服务) 也是 Serverless,还有人说使用 Serverless 就没有服务器了。
接下来我们尝试从广义和侠义两个角度解释 Serverless 的架构理念。
广义上来说,Serverless 是一种后端架构理念,或者说是一种思想、概念,直接翻译过来叫做**“无服务”**,但不要被字面意思舞蹈,这并不代表应用运行不需要服务器。在 Serverless 时代之前,我们可以将传统架构统称为 Serverfull 时代,意思就是关于服务器的一切,我们都需要人工干预,而 Serverless,更准确的说,应该是开发者不用关心服务器的意思,是将服务器相关的工作交给云平台来做。对于开发者来说,与服务器运维有关的所有工作都不再关心,Server(服务器)是不可能真正消失的。
2019 年 2 月,UC 伯克利大学发表了一篇标题为《Cloud Programming Simplified: A Berkeley View on Serverless Computing》的论文,论文中有这样一段对 Serverless 的描述:
在云的上下文中,Serverful 的计算就像使用低级的汇编语言编程,而 Serverless 的计算就像使用 Python 这样的高级语言进行编程。例如 c=a+b 这样简单的表达式,如果用汇编描述,就必须先选择几个寄存器,把值加载到寄存器,进行数学计算,再存储结果。
这就好比今天在云环境下 Serverful 的计算,开发首先需要分配或找到可用的资源,然后加载代码和数据,再执行计算,将计算的结果存储起来,最后还需要管理资源的释放。
如果你不是计算机专业,可能感知并不是很强烈,但从计算机专业的角度来讲,这样的比喻非常清晰。Serverful 是我们今天主流的使用云的方式,但不应该是未来我们使用云的方式,Serverless 所希望的,是开发者用代码去支撑业务六级,而对于资源的管理交给工具和云。
在 Serverful 的架构下,我们需要关心的问题非常多,比如:根据业务流量大小等指标,响应式地调整服务规模,实现自动弹性伸缩;再比如异地容灾、负载均衡、日志监控、文件存储等等,解决这些复杂地问题需要投入大量地人力、物力,而在 Serverless 架构下,开发者只专注于开发业务逻辑,所有的这些与业务无关地基础设施,全部交给云平台负责,由云平台统一调度、运维。
在这样的理念指导下,各家云平台场地上,都有不同实现方案,每家云平台提供的 Serverles 服务,都或多或少的存在差异。
但是,按照 CNCF(云原生计算基金会)对 Serverless 计算的定义:
Serverless 架构应该是采用 FaaS(函数即服务)和 BaaS(后端即服务)服务来解决问题的一种设计。
这样的定义从应用落地的角度来说,更加的具体可行,也让我们对 Serverless 的理解更加的清晰明了。
因此从应用落地的角度,狭义的 Serveless 就是 FaaS + BaaS 组合。
那么 FaaS 和 BaaS 分别是什么呢?
前面说,Serverless 把后端架构的工作全部包揽下来,硬件的维护,集群的管理,运行环境的搭建,全部由云平台完成,除此之外,像缓存、数据库、文件存储、消息中间件等,也全部有云平台帮我们做好,封装起来,以接口的形式提供服务,这就是 BaaS。
所谓后端即服务,对于开发者,BaaS 就是一个黑盒,你不用知道我怎么做,更不需要关心我如何做,你需要什么过来拿就行了。
但是,我们需要向数据库存一条数据,用户上传的照片我们需要裁剪以后存到文件存储中,这是需要我们编写业务逻辑代码完成的功能。假设我们现在已经把这些逻辑代码写好,用的是 Node.js,,前面说所有的服务器及运行环境都放在了 BaaS 这个黑盒子中,我怎么让这些代码运行呢?换句话说就是,我现在写的逻辑代码,是需要 Node.js 这个运行环境的,怎么办?
我们只需要将写好的代码,交给 Serverless 就行了,Serverless 中有专门运行我们的逻辑代码的地方,这个地方就是 FaaS。
FaaS 是以函数的方式运行我们的代码的,本质上 FaaS 就是一个函数运行平台,大多数的 Serverless 云平台提供的 FaaS,都支持 Node.js、Python、Java、PHP 等编程语言,你可以选择你喜欢的编程语言编写函数并运行。
对于开发者来说,使用 FaaS 几乎就是使用 Serverless 的一切了,在 FaaS 中,我们能够体会到 Serverless 全部的特性。
首先,FaaS 函数运行时,开发者对底层的服务器是无感知的,FaaS 产品会负责服务器资源的调度和运维,这些就是前面说的 BaaS,这也是 Serverless 最大的特点:无运维。
其次,FaaS 中的函数也不是持续运行的,而是通过一定的条件进行触发,比如 HTTP 事件、消息事件、定时器事件等,产生事件的源头叫触发器,FaaS 平台会集成这些触发器,我们直接用就行,这是 FaaS 的第二个特点:事件驱动。
再者就是 Serverless 的付费方式了,与其它云产品不同的是,Serverless 的付费方式是按量付费,是按照 FaaS 函数执行次数和执行时消耗的 CPU、内存等资源进行计费的,用多少付多少,不用不付费。
同时,FaaS 会根据并发量自动生成多个函数实例,BaaS 会根据函数运行所需要的资源量自动调配服务器资源,理论上的资源调用量没有上限,这也就实现了不同访问量的弹性伸缩了,而且是实时的弹性伸缩。
基于 FaaS 和 BaaS 的架构,是一种计算和存储分离的架构。计算由 FaaS 负责,存储由 BaaS 负责,计算和存储也被分开部署和收费。这使应用的存储不再是应用本身的一部分,而是演变成了独立的云服务,降低了数据丢失的风险。而应用本身也变成了无状态的应用,更容易进行调度和扩缩容。
基于 FaaS 和 BaaS,你的应用就实现了自动弹性伸缩、按量付费、不用关心服务器,这正是 Serverless 架构的必要因素。所以说狭义的 Serverless 是 FaaS 和 BaaS 的组合。
前面介绍的 Serverless 的特点实际上也是它的有点,简单总结它的优点:
Serverless 并不是十全十美的,它也存在很多缺点,了解它的缺点,可以让你今后更好的进行技术选型,决定是否用 Serverless 进行应用开发,下面具体介绍它有哪些缺点。
Serverless 的能力是云厂商打包提供的,所以 Serverless 产品一定是和云厂商绑定的,又因为 Serverless 理念和具体实现之间并没有统一的标准。
比如 A 厂商认为 Serverless 的数据库必须使用标准 SQL 规范,而 B 厂商则认为数据库可以使用 SQL 规范也可以使用 JSON 文件的存储文案。
这就出现了不同的云厂商实现了不同 FaaS 接口,我们的同一套代码,是无法在不同的 Serverless 产品上运行的,要想从一个云平台迁移到另一个云平台,成本非常高。
Serverless 应用依赖的云服务,难以在本地环境搭建,要想在本地开发调试非常复杂。
同时,Serverless 架构正处于飞速发展的阶段,其开发、调试、部署工具链并不完善。
目前 Serverless 的技术实现是 FaaS 和 BaaS。我们的应用代码在 FaaS 上运行,但 BaaS 是个黑盒,其底层的硬件资源是不确定的,某些场景下,代码必须运行在某种类型的 CPU 或 GPU 上,目前云厂商并没有提供针对底层硬件的可选项。
这一点对前端开发者来说并不是特别重要。
Serverless 还有很多特性没有介绍,包括其它优缺点、运行机制、开发方式等,下面通过具体的应用实践,深入感受 Serverless 的架构理念,补充对 Serverless 其他特性的介绍。
前面说 Serverless 是和云厂商绑定的,所以需要选择一家云平台服务商,例如阿里云、AWS 以及腾讯云提供的 Serverless。
本例使用腾讯云,并不是其他厂商不好,只是相对于其他厂商,腾讯云提供了非常友好的手册及教程,如果你是用过小程序的云开发,那么对于腾讯云你会感到非常熟悉。腾讯云开发文档中心
前往腾讯云官网,注册登录腾讯云账号。
申请开通 云开发 CloudBase 产品,进入控制台,创建应用:
腾讯云云开发提供至多1个环境的免费资源,根据需要选择是否勾选开启免费额度,具体参考:免费额度的官方说明。
创建成功后选择正确的**“地域”**可以查看应用,点击应用进入配置页面,创建云函数:
运行环境:本文编写时 Nodejs 已经发布到 V18,但是这里最高只能选择 V12,这是因为每一种编程语言在 Serverless 的运行环境中都要做大量的适配,而最新的版本出来后,云服务器有大量的工作要做,所以更新比较慢,这也是 Serverless 的一个缺点,就是没有办法使用比较新的一些语言特性。
函数内存:是使用或运行这个云函数时可以调用的最大内存。
函数代码可以稍后修改,创建成功后,点击列表中的函数名称就可以进行修改了:
腾讯云提供了一个基于浏览器的类似 vscode 的在线编辑器,日常开发不用这个,修改后 Ctrl + s
可以临时保存,但要点击下面的**【保存】**按钮才会真正使修改生效。
index.js
是入口文件,其中的 main
函数是入口函数,入口文件和入口函数是可以更改的,但是一般不建议更改。
入口函数接收两个参数 event
对象和 context
对象。
event
对象:触发云函数的事件。例如:
event
是小程序端调用云函数时传入的参数event
是集成请求体context
对象:包含了此调用的调用信息和函数的运行状态,可以使用 context
了解服务运行的情况前面说过,FaaS 产品的一大特性是事件驱动,要想让函数代码执行,需要创建要给事件的触发器。我们比较熟悉的就是 HTTP 触发器了,在腾讯云它叫 “HTTP 访问服务”,点击新建:
创建触发器要等待几分钟,等待创建成功后,我们就可以使用默认域名,访问应用函数:<默认域名>/hello
,也可以通过点击访问服务列表中的“触发路径”直接跳转。