Serverless 目前是大热的话题,相信你肯定听过,但如果你去百度、Google 或者维基百科上查的话,你会发现它连个准确的定义都没有。
什么是Serverless?为什么Serverless最近这么火?
今天我就带你深入地了解下 Serverless,看看这到底是什么?
Serverless 能解决什么问题?
从字面意思理解,Serverless 包含 server 和 less两部分,Server 这里指服务端,它是 Serverless 解决问题的边界;而 less 我们可以理解为较少关心,它是 Serverless 解决问题的目的,因此,组合在一起,Serverless 就是“较少关心服务端”。
什么是服务端?
我们先看 Server,这里我用 Web 应用经典的 MVC 架构来举例。
MVC 架构主要分为前端和后端,前端负责客户终端的体验,也就是 View 层;后端负责商业的业务逻辑和数据处理,也就是 Control 层和 Model 层。如果你有过一些开发经验,应该会了解自己的代码在本地开发和调试时的数据流。
通常我们会在自己电脑上启动一个端口号,例如 127.0.0.1:3001。浏览器访问这个地址,就可以调用和调试自己的代码。但如果我们要将这个 Web 应用部署到互联网上,提供给互联网用户访问,就需要服务端的运维知识了。
如果要考虑容灾和容错,可以部署多个 Web 应用实例,以保障异地多活。而为了使多个 Web 应用实例在容灾和容错的场景下稳定地切换流量,我们需要使用负载均衡服务和反向代理服务。负载均衡服务,正如其名是负责将流量均衡地分配到各个应用机器上;反向代理常见的就是 Nginx,它的任务是从请求中解析出域名信息,并将请求转发到上游 upstream 的监听地址。
服务端的边界,就是上图中的整个蓝色部分,它是负责应用或代码的线上运维。Serverless 解决问题的边界,就是服务端的边界,即服务端运维。
服务端运维发展史,从 Serverfull 到 Serverless
我们可以先看看 Serverfull 的概念,然后对比一下 Serverfull 和 Serverless 之间的差别,相信这样可以加深你的理解。Serverfull 就是服务端运维全由我们自己负责,Serverless 则是服务端运维较少由我们自己负责,大多数的运维工作交给自动化工具负责。
可能这么说比较抽象,我举个例子来说吧。
假设我有一家互联网公司,我的产品是“待办任务(ToDoList)”Web 应用——即记录管理每个用户的待办任务列表。针对这个网站的研发,我们简化为两个独立角色:研发工程师小程和运维工程师小服。
做研发的小程,他是个精通前后端的全栈工程师,但他只关心应用的业务逻辑。具体来说就是,整个 MVC 架构的 Web 应用的开发、升级和问题修复都归小程负责。负责运维的小服,则只关心应用的服务端运维事务。比如负责部署上线小程的 Web 应用,绑定域名以及日志监控。在用户访问量大的时候,给这个应用扩容;在用户访问量小的时候,给这个应用缩容;在服务器挂了的时候,重启或者换一台服务器等。
史前时代,Serverfull
最开始运维工程师小服承诺将运维的事情全包了,小程不用关心任何部署运维相关的事情。于是,小程每次发布新的应用,都会打电话给小服,让小服部署上线最新的代码。小服要管理好迭代版本的发布,分支合并,将应用上线,遇到问题回滚。如果线上出了故障,还要抓取线上的日志发给小程解决。
小程和小服通过工作职责任务上的安排,将研发和运维完全隔离开来了。好处很明显:分工明确,小程可以专心做好自己的业务;缺陷也很明显:小服成了工具人,被困在了大量的运维工作中,处理各种发布相关的琐碎杂事。
这个时代研发和运维隔离,服务端运维都交给小服一个人,纯人力处理,也就是 Serverfull。
农耕时代,DevOps
我们可以停下来想想,其实像发布版本和处理线上故障这种工作,应该小程的职责,而不应该全部由小服协助,对不对?
实际上,后来小服也渐渐发现,日常其实有很多事情都是重复性的工作,尤其是发布新版本的时候,与其每次都等小程电话,线上出故障了还要自己抓日志发过去,效率很低,不如干脆自己做一套运维控制台 OpsConsole,将部署上线和日志抓取的工作让小程自己处理。
说干就干,OpsConsole 上线后,小服确实稍微轻松了一些,但是优化架构节省资源和扩缩容资源方案,还是需要小服定期审查。而小程除了开发的任务,每次发布新版本或解决线上故障,还要自己到 OpsConsole 平台上去处理。
这个时代就是研发兼运维 DevOps,小程兼任了小服的部分工作,小服将部分服务端运维的工作工具化了,自己可以去做更加专业的事情。
相对史前时代,农耕时代小服已经将部分人力的工作工具化了,其结果是效率变高了。此时,已经有Serverless 的趋势了。
我们再想想能否进一步提升效率,让小程连 OpsConsole 平台都可以不用?
工业时代,Serverless
小服发现资源优化和扩缩容方案也可以利用性能监控 + 流量估算解决,于是小服又基于小程的开发流程,将 OpsConsole 系统再进一步优化,帮小程做了一套代码自动化发布的流水线:代码扫描 —— 测试 —— 灰度验证 —— 上线。现在的小程连 OpsConsole 都可以不用登陆操作,只要将最新的代码合并到 Git 仓库指定的 develop 分支,剩下的就都由流水线自动化处理发布上线了。
这个时代研发不需要运维了,免运维 NoOps。小服的服务端运维工作全部自动化了,小程也变回到最初,只需要关心自己的应用业务就可以了。
我们不难看出,在服务端运维的发展历史中,对于小程来说,小服的角色存在感越来越弱,需要小服参与的事情越来越少,都由自动化工具替代了。
到这里你一定会想,既然服务端都做到免运维了,小服是不是就自己革了自己的命,失业了?
未来
实现了免运维 NoOps,并不意味着小服要失业了,而是小服要转型,转型去做更底层的服务,做基础架构的建设,提供更加智能、更加节省资源、更加周到的服务。小程则可以完全不被运维的事情困扰,放心大胆地依赖 Serverless 服务,专注做好自己的业务,提升用户体验,思考业务价值。
免运维 NoOps 并不是说服务端运维就不存在了,而是通过全知全能的服务,覆盖研发部署需要的所有需求,让研发同学小程对它的感知越来越少。另外,NoOps 是理想状态,因为我们只能无限逼近 NoOps。
另外,你需要知道的是,目前大多数互联网公司,包括一线互联网公司,都还在 DevOps 时代。只是 Serverless 的概念已经提出,NoOps 的时代正在到来。
按照上面的分解,Serverless 可以叫做服务端免运维,这也就是 Serverless 要解决的问题。
到底什么是 Serverless?
总结来说 Serverless 的含义有这样两种:
- 第一种:狭义 Serverless(最常见)= Serverless computing 架构 = FaaS 架构 = Trigger(事件驱动)+ FaaS(函数即服务)+ BaaS(后端即服务,持久化或第三方服务)= FaaS + BaaS
- 第二种:广义 Serverless = 服务端免运维 = 具备 Serverless 特性的云服务
我用图片来阐明一下这两种概念。
虽然你可以看到,广义 Serverless 包含的东西更多,适用范围更广,但我们经常在工作中提到的 Serverless 一般都是指狭义的 Serverless。这是有历史原因的,2014 年 11 月份,亚马逊推出真正意义上的第一款 Serverless FaaS 服务:Lambda。Serverless 的概念才进入了大多数人的视野,也因此 Serverless 曾经一度就等于 FaaS。
图中有几个陌生的名词,我先来给你解释下。FaaS(Function as a Service) 就是函数即服务,BaaS(Backend as a Service) 就是后端即服务。XaaS(X as a Service) 就是 X 即服务,这是云服务商喜欢使用的一种命名方式,比如,我们熟悉的 SaaS、PaaS、IaaS 都是这样。
先说 FaaS,函数即服务,它还有个名字叫作 Serverless Computing,它可以让我们随时随地创建、使用、销毁一个函数。
你可以想一下通常函数的使用过程:它需要先从代码加载到内存,也就是实例化,然后被其它函数调用时执行。在 FaaS 中也是一样的,函数需要实例化,然后被触发器 Trigger 或者被其他的函数调用。二者最大的区别就是在 Runtime,也就是函数的上下文,函数执行时的语境。
FaaS 的 Runtime 是预先设置好的,Runtime 里面加载的函数和资源都是云服务商提供的,我们可以使用却无法控制。你可以理解为 FaaS 的 Runtime 是临时的,函数调用完后,这个临时 Runtime 和函数一起销毁。
FaaS 的函数调用完后,云服务商会销毁实例,回收资源,所以 FaaS 推荐无状态的函数。如果你是一位前端工程师的话,可能很好理解,就是函数不可改变 Immutable。简单解释一下,就是说一个函数只要参数固定,返回的结果也必须是固定的。
用我们上面的 MVC 架构的 Web 应用举例,View 层是客户端展现的内容,通常并不需要函数算力;Control 层,就是函数的典型使用场景。MVC 架构里面,一个 HTTP 的数据请求,就会对应一个 Control 函数,我们完全可以用 FaaS 函数来代替 Control 函数。在 HTTP 的数据请求量大的时候,FaaS 函数会自动扩容多实例同时运行;在 HTTP 的数据请求量小时,又会自动缩容;当没有 HTTP 数据请求时,还会缩容到 0 实例,节省开支。
此刻或许你会有点疑惑,Runtime 不可控,FaaS 函数无状态,函数的实例又不停地扩容缩容,那我需要持久化存储一些数据怎么办,MVC 里面的 Model 层怎么解决?
此时我就要介绍另一位嘉宾 —— BaaS 了。
BaaS 其实是一个集合,是指具备高可用性和弹性,而且免运维的后端服务。说简单点,就是专门支撑 FaaS 的服务。FaaS 就像高铁的车头,如果我们的后端服务还是老旧的绿皮火车车厢,那肯定是要散架的,而 BaaS 就是专门为 FaaS 准备的高铁车厢。
MVC 架构中的 Model 层,就需要我们用 BaaS 来解决。Model 层我们以 MySQL 为例,后端服务最好是将 FaaS 操作的数据库的命令,封装成 HTTP 的 OpenAPI,提供给 FaaS 调用,自己控制这个 API 的请求频率以及限流降级。这个后端服务本身则可以通过连接池、MySQL 集群等方式去优化。各大云服务商自身也在改造自己的后端服务,BaaS 这个集合也在日渐壮大。
基于 Serverless 架构,我们完全可以把传统的 MVC 架构转换为 BaaS+View+FaaS 的组合,重构或实现。
这样看下来的话,狭义 Serverless 的含义也就不难理解了。
第一种:狭义 Serverless(最常见)= Serverless computing 架构 = FaaS 架构 = Trigger(事件驱动)+ FaaS(函数即服务)+ BaaS(后端即服务,持久化或第三方服务)= FaaS + BaaS
Serverless 毋庸置疑正是因为 FaaS 架构才流行起来,进入大家认知的。所以我们最常见的 Serverless 都是指 Serverless Computing 架构,也就是由 Trigger、FaaS 和 BaaS 架构组成的应用。这也是我给出的狭义 Serverless 的定义。
那什么是广义 Serverless 呢?
将狭义的 Serverless 推升至广义,具备以下特性的,就是 Serverless 服务。你可以回忆一下小服的工作,要达成 NoOps,都应该具备什么条件?
小服的工作职责:
无需用户关心服务端的事情(容错、容灾、安全验证、自动扩缩容、日志调试等等)。
按使用量(调用次数、时长等)付费,低费用和高性能并行,大多数场景下节省开支。
快速迭代 & 试错能力(多版本控制,灰度,CI&CD 等等)。
广义 Serverless,其实就是指服务端免运维,也是未来的主要趋势。
总结来说的话就是,我们日常谈 Serverless 的时候,基本都是指狭义的 Serverless,但当我们提到某个服务 Serverless 化的时候,往往都是指广义的 Serverless。
总结
Serverless 能解决什么问题?Serverless 可以使应用在服务端免运维。
Serverless 为什么难定义?Serverless 将服务端运维高度抽象成了一种解决方案,包含的信息量太大了。
狭义 Serverless 是指用 FaaS+BaaS 这种 Serverless 架构开发的应用;广义 Serverless 则是具备 Serverless 特性的云服务。现在的云服务商,正在积极地将自己提供的各种云服务 Serverless 化。