第六期 | 前端搞 Serverless

2,139 阅读17分钟

2020.5.16 前端搞 Serverless

前言

本人刚毕业不到一年的前端萌新,前端早早聊大会是一个非常不错的技术大会举办方,除了第一届没有参加,之后的每一届我都参加了。但是,前面的几届大会分享在看了一遍直播后就没有去再去关注,主要是抱着以后再看的心态吧(实际上大概率过了很长一段时间才会去关注了)。认识到之前的问题,所以打算从这届开始对每次的分享进行总结,并在平常的空闲时间里不断关注相关的信息。

本届是第六届,我将从以下几个角度对本次主题 “前端搞 Serverless” 进行简单的内容总结:

  • Serverless 为什么会出现
  • Serverless 是什么
  • Serverless 如何使用
  • Serverless 如何设计
  • Serverless 的出现与应用将会产生什么影响
  • Serverless 目前有哪些实践

声明:

  • 小白前端一枚,很早之前就在知乎上关注了 Serverless,但一直都没有去研究这一块,本篇总结就当是我对 Serverless 的入门吧。本文为总结感悟型文章,文中如果有涉及侵权的东西,或者说错的东西,希望各位大佬能够指出,谢谢!!!

  • 从未接触过 Serverless,由于时间问题,最近也只是通过阿里云的简单 Serverless 实例玩了一下,也希望和各位大佬交流与学习!!!

  • 本篇文章是我在掘金的第一篇文章,个人平时更新的文章也是在 csdn 和知乎上,贴一下知乎和 github (最近才开始专注造轮子,所以开源不多)的链接地址,也希望能和各位小伙伴或大佬在这些平台上交流与学习:www.zhihu.com/people/bi-a…github.com/yaodebian

  • 本篇文章涉及东西比较多,由于时间问题,后期会视情况进行更新。

  • 最后,简洁自我介绍一下,yaodebian 或者说 “垚的彼岸” (之所以提这个是因为很多人把 yaodebian 都成 “要的编”)是我常用的昵称,“冬沐” 是我的花名(如果以后能进阿里的话),废话到此为止(逃。。。

Serverless 从无到有的演变历程

在具体分析这个演变过程之前,我觉得有必要对 “前后端”(web) 的发展历程有一定的认知。

前端到全栈的演进

前端发展历程

这张图展示了前端发展的一些历史节点:

  1. 在ajax出现之前,web开发结构体系与流程大致是这样的:

web开发结构体系与流程

没有 FrontEnd 与 BackEnd 的区分,所有的工作都是由一个岗位负责。

  1. 随着 ajax、基于 ajax 技术的一些 js 库(jquery)以及 jsp 等的出现,前端工作开始变得复杂。

  2. 随后,2015 年谷歌提出 PWA 概念,多种前后端分离 web 框架兴起(如今的 angular、vue、react),webpack、gulp等一些打包工具的出现。。。如今,前端已经具备工程化开发、组件化开发,复杂度已不输于后端,前后端已真正实现分离分工(虽然一些老项目还是 JSP):

行业分工,一般我们都会有三个概念:前端、后端、全栈。

全栈开发工程师,从掌握技术的角度来看,只要同时掌握前端技术和后端技术就是全栈(或者有些更加简单的看法是:会写页面 + 会写接口 + 会调数据库)。

但实际上全栈的要求远远不止如此:

全栈(或者说架构)不仅要掌握前后端技术,还要懂业务、会架构(代码结构、性能优化、前端架构、后端架构等)。

这块具体我不是全栈我不熟(逃。。。

Serverless 从无到有

  1. 史前时代,Serverfull

开发者只需要专注业务开发,开发完之后,将会有单独的运维人员负责迭代版本的发布、分支合并、将应用上线、遇到问题回滚,如果线上遇到问题,需要开发协助把问题解决后再发布。

  1. 农耕时代,DevOps

这时候有了运维控制台 OpsConsole,通过它,开发人员可以自行发布迭代版本,自行抓取错误日志。

  1. 工业时代

OpsConsole 系统进一步升级,通过流水线的方式将代码自动化发布:

代码扫描 -> 测试 -> 灰度验证 -> 上线

现在研发连 OpsConsole 都可以不用登录,只要将代码合并到git仓库指定的分支,剩下的 Opsconsole 将会流水线自动化地帮我们发布。

其实这就是我们目前的Serverless。

  1. 未来

对 OpsConsole 做更深入的优化:更好的节省资源、更加人性化。。。

所以Serverless的出现是时代需求推进的结果,目的是为了更好的解放劳动力,节省成本。

具体谈谈 Serverless 要解决什么问题

  1. 减少开销

    • 从服务商的角度:减小硬件开销,扩大市场,有效降低企业中中长尾应用的运营成本;
    • 应用部署人员:零运维经验分分钟部署;
    • 普通用户:用多少花多少,降低购买成本;
  2. 提高研发效能

    SFF(Serverless For Frontend)可以让前端同学自行负责数据接口的编排,微服务Baas化则让后端同学更加关注领域设计。

Serverless是什么

Serverless 这个单词由两部分组成:Server + Less,Server 指的是服务端运维,Less是指目的,即更少的运维或者说免运维NoOps。合起来就是,服务端免运维,当然,NoOps是理想态,所以是Serverless,而不是ServerZero。

定义

Serverless 目前有两种定义:

  • 狭义上(一般):

    Serverless = Serverless computing 架构 = FaaS 架构 = Trigger(事件驱动)+ FaaS(函数即服务)+ BaaS(后端即服务,持久化或第三方服务)= FaaS + BaaS

  • 广义上:

    广义 Serverless = 服务端免运维 = 具备 Serverless 特性的云服务

具备 Serverless特性的云服务可以这样理解:

  • 无需用户关心服务端的事情(容错、容灾、安全验证、自动扩缩容、日志调试等等);

  • 按使用量(调用次数、时长等)付费,低费用和高性能并行,大多数场景下节省开支;

  • 快速迭代 & 试错能力(多版本控制,灰度,CI&CD 等等);

Serverless 实践 —— 云开发

Serverless 只是一种概念,而其对应的实践则是云开发。

  1. 什么是云开发(CloudBase)?

采用Serverless架构,提供云函数、云数据库、云存储等基础资源服务,免环境搭建等运维事务,同时提供静态托管、命令行工具(CLI)、VS Code插件、Flutter SDK等能力,极大降低应用开发门槛,助力快速构建小程序、Web应用和app。

  1. 云开发的整体架构

云开发的整体架构

  1. 云开发基础能力

  1. 云开发对工程的支持有以下几个特点

    • 高效:

      • 与传统开发模式相比,云开发开箱即用;

      • 降低后端与运维成本,减少研发人力投入;(原来前端、后端、系统运维、中间件的开发可能需要 7-10 天,现在只需要前端投入 2 天)

    • 质量:

      • 云开发秒级扩容承载亿级流量;(自动伸缩,按量付费)

      • 以腾讯云为例云开发平台日调用量可承受 7 亿;

    • 安全

    • 多端

Faas(Function As A Server)

Faas是实现Serverless自动缩扩容的基础。它的作用是通过触发器的模式打通数据调用链路,以代替当前用的还比较多的 BFF 或者传统基于nginx反向代理的调用模式。

  1. 运行逻辑

Faas的请求流程是这样的:用户访问函数触发器 -> 函数触发器产生一个 HTTP Request 事件通知函数服务 -> 函数服务检查是否有函数实例,有则执行并返回数据给触发器,如果没有则先构建一个函数实例 -> 函数执行返回数据给触发器,触发器再将数据返回给用户

Faas 冷启动:调用函数开始到函数实例准备完成。

现在的云服务商,基于不同的语言特性,冷启动平均耗时基本在 100~700 毫秒之间。得益于 Google 的 JavaScript 引擎 Just In Time 特性,Node.js 在冷启动方面速度是最快的。

Faas预热冷启动:由于冷启动中有些资源加载会相比慢一些(例如冷启动过程中耗时比较长的是下载函数代码),所以一旦你更新代码,云服务商就会偷偷开始调度资源,下载你的代码构建函数实例的镜像。请求第一次访问时,云服务商就可以利用构建好的缓存镜像,直接跳过冷启动的下载函数代码步骤,从镜像启动容器,这个也叫预热冷启动。

上面这套Faas的调用链路逻辑有些人或许会觉得它和 Paas 平台类似,实际上,FaaS 与应用托管 PaaS 平台对比,最大的区别在于资源利用率:Faas 能够 0 缩容,而 Paas 不能。这是为什么呢?

  • Faas冷启动时间非常短;

  • Pass创建应用实例通常需要几十秒,为保证服务可用性,必须一直维持着至少一台服务器运行你的应用实例;(应用托管平台 PaaS 为了适应用户的多样性,必须支持多语言兼容,还要提供传统后台服务,例如 MySQL、Redis,这也意味着,应用托管平台 PaaS 在初始化环境时,有大量依赖和多语言版本需要兼容,而且兼容多种用户的应用代码往往也会增加应用构建过程的时间)

通过分层结构进一步提升资源利用率:Faas 实例执行时,至少分为三层结构 —— 容器、运行时 runtime、具体函数代码。可以这么想象,容器是一个操作系统,运行时是一个播放器,函数代码为某部电影MP4文件。(个人理解,通过这样的分层结构,使得这三层结构解耦,对应的资源都是单独加载,不需要等待另一部分也加载完,这样便能加快 Faas 的冷启动时间,具体没接触过所以不清楚,就不多说了)

  1. Faas 的两种进程模型与应用场景

Faas 的两种进程模型分为 “用完即毁型” 和 “常驻进程型”。

“用完即毁型”:函数实例准备好后,执行完函数就直接结束。这是 FaaS 最纯正的用法。

“常驻进程型”:函数实例准备好后,执行完函数不结束,而是返回继续等待下一次函数被调用。这里需要注意,即使 FaaS 是常驻进程型,如果一段时间没有事件触发,函数实例还是会被云服务商销毁。(基于传统的 MVC 架构应用如果直接迁移到 Serverless 架构云开发平台上,可以采用这种进程模式,个人理解是因为因为传统架构代码如果不做 Serverless 重构,将会使得冷启动时间增加,所以通过这种模式可以勉强减少冷启动时间长导致的不友好型)

目前用的比较多的数据编排模式是 BFF,但如果迁移到 Serverless,则可以选择SFF,因为 Faas 的 Trigger 可以认为是一层数据清晰度层。

与数据编排类似,服务编排是对云服务商提供的各种服务进行组合和加工。个人理解就是:我们的Paas服务里面是可以添加基于不同运行环境的函数,基于这些函数(nodejs、java、php等)进行组合,可以增加整个应用的灵活性,即服务不再受限于单一的语言,场景多样化。

  1. Faas 如何快速扩缩容

Faas 默认的扩缩容方式是横向扩缩容,也就是提升机器数量,价格平稳。

需要注意的是,扩缩容的节点只能是 stateless(无状态)节点,而 stateful(有状态)的节点则是用来存储数据。

什么叫带状态:

应用状态就是应用组件完成他们的工作(即执行任务)时所需的数据。从软件的架构、编码的范式到编程语言本身都离不开应用状态的参与,应用状态实质上说明了着怎样去管理一个应用的行为(任务,操作等)和状态(数据)。(状态如:全局变量、本地文件存储、长链接等,个人理解是某个单独的节点存在与其他同类节点不同的行为,那么这类节点则是 stateful,比如数据库扩容的机器肯定没有原来的机器的数据,它需要把原来机器上的数据同步过来,这中间是有时间成本在的,所以不能任意扩缩容)

Baas

Faas 避免直接操作数据库,因为操作数据库时需要做连接数据库操作,而这个操作将会直接拖慢 Serverless 的冷启动。所以传统的数据库操作则通过 Baas 服务进行了封装。

  1. NoOps的微服务

Baas 服务实际上运用了微服务,当前模块拆解成职责单一的小功能模块,各模块之间的数据模型相互独立,模块采用 API 接口暴露自己对外提供服务。

那么如何解决数据操作的 stateful 问题呢:

通过额外进程让数据库与副本直接通过消息队列进行同步,所以对于微服务应用来说,只需要关注自身独享的数据库就可以了。微服务通过数据库解耦,将后端应用变成 Stateless 的了,但对后端应用本身而言,数据库还是 Stateful 的。(个人理解是对当前数据库的读写操作都会通过消息队列来进行记录,相当于日志,然后基于消息队列,再将这些操作同步更新到其他扩容出来的数据库节点上,会有些许的时延性,所以从外部看整个 Baas 服务,他是 Stateless,但是根本上它还是 Stateful)

  1. 业务逻辑的拆与合

Baas 服务是基于微服务的概念,那如何拆解 Baas 服务可以转换成如何拆解微服务,这里就有个 DDD 思想:

通过对业务分层抽象,分析定义出领域模型,用领域模型驱动我们设计系统,最终将复杂的业务模型拆解为独立运维的领域模型。

拆解完之后,就要考虑合。我们可以通过事件流的编排思想,通过事件顺序将我们的微服务或 Faas 串联起来。

如何通过 Serverless 构建应用

  1. Serverless 构建应用只需三步即可完成

也就是:安装与初始化 → 配置 yml 文件 → 部署

  1. 或者我们需要定制化自己的 Serverless 组件依赖,则我们需要进行以下几步:

最后基于开发的组件初始化 Serverless 应用并配置 yml 文件、部署。

如何设计 Serverless 架构(以阿里为例)

  1. 解决方案的重点
  • 建设一个独立的网关;

  • 建立一个在线统一的开发流程平台;

  • 补足现有 Baas 的能力;

  1. 抽象高频场景

  1. 构建研发流程

传统的开发流程是本地通过 cli 脚手架构建项目模板,然后再构建与部署到线上环境(配备一些日志、监控、调试的能力),接入层则是通过 nginx 方向代理请求。

而通过 Serverless,个人理解是通过 Serverless 流程平台,基于平台上已有的相关环境的函数模板进行项目初始化然后再开发,同时为了统一运行时环境,通过线上 Docker 统一构建同样的环境,当然也不再需要去手动或自动化配置 nginx 代理,因为基于 Serverless,可以直接基于 Trigger 进行请求访问与代理。

  1. 验证区分版本

每次迭代都会有代码修改,修改之后 gitlab 上面的提交就会有一个唯一的commitId,当应用在部署的时候,Serverless 平台会首先从某个 git 分支上拉取代码,并在某个过程中取出 commitId,并通过某种手段基于 commitId 生成一个路由,最后线上的访问则基于生成的路由访问部署的项目。

  1. 本地开发支持远程调试

  1. 网关

通过把请求上下文同步到接入层中,当流量请求过来时,则可以通过请求上下文确定要执行的函数。

  1. Baas 能力

  1. 领域模型

这部分个人的理解是这样的:中后台的领域模型存在较多耦合,甚至是领域模型中还存在某些单独构建的领域模型,所以我们需要基于这些领域模型单独去构建函数。而导购不同,其结构是单一的,我们所要做的是裁剪出我们我要的数据,所以可以通过某个方案自动化地由模型去生成函数,而不需要单独为某个领域模型构建对应的函数。

Serverless 对前端与后端的影响

Serverless 对前端来说能带来什么

  • 行业定位发生变化:serverless化之前只需要面向UI开发,serverless化之后面向整个应用(业务)交互;

  • 协同和开发模式、上下游流程也会发生变化;

Serverless 对后端来说能带来什么变化

  • 从更底层提供能力支持(比如:专注 Baas 服务拆分);

  • 未来的成长方向将可能是偏业务解决方案的行业架构师;

  • Serverless为后端提供了相应的在 Serverless 架构构建领域的机会

Serverless 的实际运用

服务器厂商

目前的 Serverless 的服务器厂商,国内有腾讯云和阿里云两家,国外有 Aws 等。

开源项目

  1. midway faas( github.com/midwayjs/mi…

Midway FaaS 是一个用于构建 Node.js 云函数的 Serverless 框架,可以帮您在云原生时代更专注于产品开发,降低维护成本。

上面这张图描述了midway faas的一些特性和支持,对我而言它吸引我的是它支持国内主流的两家服务商、nodejs框架(eggjs 与 koajs),同时支持主流的前后端分离框架。

它的体系架构如下:

  1. Serverless( github.com/serverless/…

The Serverless Framework ——快速部署你的 Serverless 应用,支持事件触发,弹性扩缩容,并且按需付费。从而大大降低构建和维护应用的开销,供开发者专注业务逻辑。

Serverless Framework 是一个命令行工具,它使用基于事件触发的计算资源,例如腾讯云云函数 SCF,AWS Lambda 等。此外,Serverless Framework 为开发和部署 Serverless 架构提供脚手架,自动化工作流以及最佳实践。并且它支持通过丰富的插件进行功能扩展。

关于前端早早聊大会:前端早早聊大会目标成为用得上、听得懂、抄得走的技术大会,计划 2020 年办 >= 15 期,由前端早早聊与掘金联合举办,前端早早聊大会行程动态、录播视频/PPT/讲稿资料下载请关注 「前端早早聊」 公众号跟进。

5 月 30 日举办第七届 - 前端如何搞微前端,报名请戳:www.huodongxing.com/go/tl7 ,海报及讲师行程如下:

5 月 31 日举办第八届 - 前端跳槽的新攻略,报名请戳:www.huodongxing.com/event/25439… ,海报及讲师行程如下: