认识 Serverless
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 的相关理念更值得开发者探讨和学习。
技术圈对 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 分别是什么呢?
- FaaS 是 Function as a Service 的缩写,直译过来就是“函数即服务”。
- BaaS 是 Backend as a Service 的缩写,直译过来就是“后端即服务”。
前面说,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 产品一定是和云厂商绑定的,又因为 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
是小程序端调用云函数时传入的参数 -
在使用 HTTP 请求的形式调用时,
event
是
集成请求体
-
在小程序端调用时,
-
context
对象:包含了此调用的
调用信息
和
函数的运行状态
,可以使用
context
了解服务运行的情况
创建触发器
前面说过,FaaS 产品的一大特性是事件驱动,要想让函数代码执行,需要创建要给事件的触发器。我们比较熟悉的就是 HTTP 触发器了,在腾讯云它叫 “
HTTP 访问服务
”,点击新建:
创建触发器要等待几分钟,等待创建成功后,我们就可以使用默认域名,访问应用函数:
<默认域名>/hello
,也可以通过点击访问服务列表中的“触发路径”直接跳转。