近期在准备部门内部的一个分享,思考了一些主题,最终还是决定结合自身 Web 服务端开发经验,来分享自己调研 Serverless 无服务建构的相关内容。

以下全文是前期准备阶段调研和整理的一部分资料,梳理总结后,在制作 Slide 过程中书写逐字稿缩减而来的。分享结束后还会继续在这部分挖掘和实践,云计算中的 Serverless 是一个非常大的主题范畴,单凭这一篇文字是没办法细说全部,笔者也在路上,感兴趣的同学可以留言讨论,持续关注。

云计算热度不减

当今社会技术热点一直围绕区块链、AI、机器学习等领域,它们背后离不开云计算的支撑。云计算在经历多年的发展,从基础设施到应用场景拓展和落地方面,都已经取得了长足的进步,大到国家层面的云计算中心纷纷落地,小到商业上各大云服务商和互联网IT厂商纷纷推出各自的云产品。在众多云计算解决方案中,Serverless 逐渐崭露头角,受到了很多关注并且发展迅猛,如果你也像笔者一样感兴趣想了解一下的话,那么请继续阅读吧!


提到云计算的发展,我们可以先来简单了解云计算应用架构在没有出现 Serverless 概念之前的演进过程。

软件应用架构和云服务的演进

首先,先来通过一张网络流传很久的 Pizza as a Service 图来了解一下几个缩写,图源来自 Medium Blog

  • IDC:Internet Data Center 自建互联网数据中心,通俗讲就是硬件机房,自行维护硬件资源、物理机器、网络环境、机房温控等等等等,在开发阶段完成后,还需要进行繁重且耗时很长的部署过程。对应的就是左侧第一个传统部署的方案。
  • IaaS:Infrastructure as a Service 基础设施服务,租用公共数据中心的物理机器资源,节省了一部分机器的成本。
  • PaaS:Platform as a service 平台即服务,软件厂商提供一个平台,使用者只需要接入这个平台,就可以使用服务。
  • SaaS:Software as a service 软件即服务,面向普通用户,用户只需要购买和使用软件就可以享受这种服务,像 Oracle 和用友财务软件、日常使用的 ERP 系统、办公自动化系统的软件等等,笔者之前所在的公司就是从事这类软件的研发,有固定的人群使用软件解决他们的问题。

从左到右的演进的过程,我们可以看到的是软件应用架构在这个过程中,一步一步地将环境、硬件、部署、运维与开发进行了分离。

近期 Pizza as a Service 更新 2.0,将近期火热的 CaaSFaaS 页加入到其中,如下图:

CaaS 容器即服务,它是基于以 Docker 为主的容器技术,还有由 Google 开源的 Kubernetes(K8S)进行容器自动编排等技术兴起而形成的一个服务架构。它将整个应用拆分成独立的微小的部分,实现快速部署,提供细粒度的微服务。

FaaS 就是 Serverless 中的其中一种方案,也是我们本文关注的重点。


好了,讲了一些枯燥的概念,那么我们回到我们的目前的工作岗位和内容。

受限

作为一名前端工程师,大家日常业务开发的工作内容是什么?

切图还原业务功能视觉稿;用浏览器脚本去完成交互;调用数据接口、完成业务数据的展现或者操作;开发 UI 组件库;开发工程化共建工具;开发应用系统;参与服务端、客户端所谓大前端的融合;开发一款轻量的客户端游戏等等等等。

这些或许都是作为一名前端工程师的工作内容。
笔者日常工作和平时了解到前端工程师大概是以上这些内容,如果有遗漏欢迎补充讨论。

现在请大家换一个角度思考,如果我们没有所谓公司的既有平台、如果我们正处创业初期、如果我们是一名独立开发者、如果没有从开发到部署的完善的整套流程、没有 CDN、没有数据接口,我们要如何开发一个动态数据的网站或是一个独立的应用?

根据以往的经验,在开发业务功能的过程中对于依赖的服务、数据等,我们一般话语权不高,仅仅是服务的使用者,那么我们能成为服务的生产者吗?

有的朋友会说:“我可以用 NodeJS 写服务,自行维护 SQL、NoSQL 作为数据支撑,在容器构建运行,最终对外提供服务!” NodeJS 帮助我们这些善于写 JavaScript 代码的前端工程师,拓宽工作范围和内容,笔者所在的部门内部基于 NodeJS 开发系统和应用都是很好的例子,我们可以写越来越多的服务端逻辑,来直接提供服务。

这里简单提一下 GragphQL 这类方案不在本次分享的范围内,它的出现使得数据更具有弹性,但笔者认为 Serverless 的出现让服务的产生更彻底更直接。

同样困惑

那么,回到文中最开始说的披萨服务模型,如果不借助云服务,就会遇到这样的困惑。要选什么样的容器作为载体,什么配置的硬件机器,几核 CPU、内存、网络带宽;如果选择要选择云服务商云主机,可能有的同学会考虑,去亚马逊、微软、Google Cloud、阿里云、腾讯云、新浪云、华为云、京东云等等这样云厂商这里“选购”各种让人眼花缭乱的“配置组合”的云主机,让人非常苦恼。

既要为应用规模大小、扩容需求、安装哪一种操作系统、配合哪一种数据库、未来如何组成集群、如何做负载均衡、如何打通开发到部署流程等等等等问题而操心。即便是现在有 Docker、K8S 这样的容器技术和自动编排来辅助,他们虽然可以帮助你做到应用秒级部署,快速重复部署,也依然麻烦,仍然需要付出高昂地运维技术的学习成本,即便你是一个全能达人,你也需要花费大量的时间和精力去解决这些环境和资源的问题,这就对想快速实现一个点子开发出原型或者开发一个小型应用的你来说,像是拦在路上的不得不跨越的一座山,拖慢来你和你团队的行进速度。

利用率低下

绝大部分应用在云主机或虚拟机上线后,其 CPU 利用率、内存使用率、网络带宽的利用率都非常低,因为你在选购过程中就要为未来新增的流量做好缓冲,你的服务一旦 7X24 的上线运行,你就要为这些冗余的运行时产生的费用自掏腰包。我们现如今公司内部的基于私有云架构开发和部署也是如此的问题,都是需要开发者为这些运维相关的技术债务来埋单,有的同学也会经常收到自动监控系统发出的效率低的提示邮件。

那么既然有这么多困难,我们前端工程师还有机会吗?

希望总是会有的!


转变

Serverless 架构的出现,为我们提供了一个窗口。目前还没有一个普遍公认的权威定义,最新的一个定义是这样描述的。

“无服务器架构是基于互联网的系统,其中应用开发不使用常规的服务进程。相反,它们仅依赖于第三方服务,客户端逻辑与托管远程服务之间的调用过程的组合。” – Wiki

这个概念在 2012 年由 iron.io 公司首先提出,而在 2014 年由 AWS 发布 Lambda 时正式商业化使用,目前 AWS 在云计算市场占有率高达 44%(2017 年数据)可以说是业界大佬,同时 Microsoft、Google、IBM 等国际大型 IT 公司都有对应的云产品;在国内,像京东云、阿里云、腾讯云、华为云也都提供了基础的功能,并且据说阿里内部正在力推适合的场景从其他框架向 Serverless 架构转变,从几个阿里前端的 BLOG 、讨论、以及业界大会分享主题来看,可以看到很多人在关注这种架构。

Serverless

支持 Serverless 架构的云厂商,允许使用者可以开发服务端逻辑,并将其放在无状态的云计算容器中,由事件来进行触发,其他完全交给云来管理。

Serverless 分为两种:

  • BaaS Backend as a Service 后端即服务 如文件存储、数据存储、推送服务、身份统一验证等,我们平时写 NodeJS 或者 Java 都是接触不到的,不是这次讨论的主角。
  • FaaS Functions as a Service 函数即服务 服务商提供一个平台,提供给用户开发、运行和管理这些函数的功能,而无需搭建和维护基础框架。这是我们关注的重点

FaaS

FaaS 是一种事件驱动的由消息触发的函数服务。函数 Function顾名思义,计算机编程领域上的函数,有着最基础的定义,就是调用函数传入 INPUT 得到输出 OUTPUT,函数内部对于使用者可以是黑盒的,这云计算中也就可以理解成为是一种函数的服务。云厂商一般都会集成很多同步或者异步的事件源,通过订阅这些事件,去达到条件触发、定时触发来运行某一个云函数的效果。FaaS 允许我们上传一个完整的函数代码片段,这个函数理论上提供单一的无状态的服务,当事件触发执行这个函数的时候,它会创建实例、启动并开始执行,完成服务后等待被销毁,不存在上下文信息和状态。换言之,就是如果函数不运行,这个实例就不存在,云厂商的计费方式也发生了调整,既然没有实例存在运行,造成损耗,那么就没有产生计费。

可以直接理解为:只有当你的函数执行的时候才会按照运行次数收费,如下图,我们关心的只是应用层中的函数部分!

事件触发,给大家举一个类似例子,有一款老牌网络应用:

IFTTT:汇聚了世界各种有趣的 API ,通过触发一件、一件事来形成链式的调用完成有趣功能。比如,当你打一辆 Uber 回家的路上,当快到家附近的时候,它会自动触发家里的灯打开,空调开启;比如,你发布一个 Instagram Photo 会自动将图片存储到 Google Photo 或者同步到微博;诸如此类,都是当发生一个事件的时候才去触发下一个事件;FaaS 可以与 BaaS 通过事件订阅来做到联动。

应用场景

AWS Lambda 官网文档Google Cloud Functions 官网文档,举了几个的应用场景,其中包括物联网 IoT 、独立应用 、游戏后台服务引擎、 数据报表(定时)等等。

貌似看上去离前端有些远,再举一个例子,2018年微信小程序提出的云开发,我个人理解也是对 Serverless 的一次尝试,让拥有开发小程序的工程师,不必依赖传统服务端,而利用云存储、云数据库、云函数来实现自给自足。

客户端开发,可以自行将数据、文件、信息同步到云端,而又不需要过于操心运维。

DEMO Express

接触新技术时,工程师们总是喜欢拿来直接上手实验,这里笔者使用 serverless.com 提供的 example,做了一个用于 TODO 应用的 server 端,使用 AWS Lambda, API Gateway, DynamoBD, S3 等服务,整体代码只有 200 行,其中 5 个 Function 服务,拥有 CRUD + Query 的功能。

如此以来,就拥有服务端的 API 服务,客户端就调用这几个服务,一个简单的 GTD 应用的雏形就已经完成了!

FaaS 优势

可以说 AWS Lambda 在市面上探索和发展的最久,用户量最大,Lambda 目前已经可以支持 Python、Java、Go、Ruby、.Net、NodeJS 和自建环境,这几个服务端语言都有自己擅长的场景和成熟的库,可以更方便地去助力完成数据计算、机器学习、图像处理等等工作。

  • 降低成本(开发、运营成本)
  • 计费方式按价值付费,不再为 7x24 埋单(即使遇到网络攻击,也可以设定阈值做到合理防护,不至于收到天价账单)
  • 灵活自动拓展,无需关心扩容缩容问题
  • 开发人员更专注核心业务

看上去万能?

No silver bullet. - The Mythical Man-Month

任何解决方案都不是万能的,一定是有它适合的场景,解决适合的问题而存在。

缺陷

  • 启动延迟、不适合长时间运行,支持语言版本更新不及时(AWS NodeJS 8.10)
  • 没有上下文环境,离线调试困难(serverless offline)
  • 完全依赖云,貌似是一条无法回头的路(是否一切都要部署到云端,这个一直处在争论中,本文也持中立态度,要分场景适用。)
  • 函数之间调用,目前还是比较保守的,AWS 已经提供这样的方案,但仍然不想传统服务与服务之间的调用的易用,其中一个非常严重的亟待解决问题,就是为了避免函数之间调用异常从而出现的死循环(函数既要做小,但是如果想提供复杂功能又不得不做的臃肿,这是一个矛盾)

总结

Serverless 架构带来的价值和挑战是并存的,国内的 Serverless 发展也在初期阶段,它改变了我们开发模式,也改变软件系统的一部分设计,未来发展的好坏,我们无法控制,但是我们可以保持关注,适当尝试。

参考资料