You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
16 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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