前言
最近两年,Serverless 这个概念非常火热,其能带来的弹性伸缩、快速开发、无运维等特性也深深吸引了众多优秀的实践者。
酷家乐技术团队自 2019 年底开始实验性地落地 Knative 作为酷家乐函数计算基础设施,同时自研以 Node.js 语言为主的 faas 产品来赋能公司内部业务方。
本文主要介绍 Serverless Faas 在酷家乐的落地方式以及对未来 faas 发展的一些看法。
1. 对 Faas 平台的理解
随着云计算服务体系的发展,慢慢演进出 Iaas(Infrastructure As A Service) ,Caas(Container As A Service) ,Paas(Platform As A Service) 和 Faas (Function As A Service) 等服务模型。
根据上图蓝色方块可知, 每个服务模型的弹性单元是不一样的。
服务的可拓展粒度正在越变越小,这也代表着开发者需要关注的内容越来越少。
无论是哪种服务模型,其目的都是通过封装行业现有认可的基本解决方案和架构,提供给用户业务快速启动的能力。
Faas 是一种相对较新的服务模型,以函数做为服务,也是当前 Serverless 主流表现形式。
在该服务模型下,用户只需要关注函数逻辑即可完成服务开发,而不需要去关心复杂的应用维护和基础设施建设。
Faas 平台(fPaas)是为用户提供开发、运行和管理的函数服务平台。
以承载 ”函数“ 的方式来启动基础应用框架,并对应用实现资源编排、自动伸缩、全生命周期覆盖、底层资源联动等保障,从而实现云服务的 serverless。
2. Faas 可以带来的业务收益
Faas 带来的最大好处,就是可以让业务快速启动,免去运维、维护的烦恼
这里从 "开发模式、分工方式、框架设计、实现过程" 四个角度介绍下当前业务开发存在的困难点:
- 在传统业务开发模式中,技术栈、方案往往都会因公司规模、团队而异,如果没有持续做技术沉淀,基本没法复用,各组内选型自由,导致业务间切换成本很高。
- 在传统业务分工方式中,前端由于涉及到服务端知识的学习成本,无法自行开发和维护 BFF 之类的适配层,后端也因接口定义多、乱而导致系统结构复杂。
- 在传统业务框架设计中,既要考虑各种技术细节和业务因素,还要考虑后期的维护和升级等等,业务开发前期的沉没成本非常高。
- 在传统应用实现过程中,服务器资源申请、构建部署、服务质量、服务稳定性等基本服务要求,都需要耗费大量的人力成本去维护。
通过 faas 的服务开发方式,可以较好的用来解决上述问题:
- "统一" 了业务组间的业务实现方式,业务切换快
- 消除服务端技术壁垒,可以使用熟悉的技术栈做业务逻辑开发
- 对用户 ”无框架“ 概念,用户只需要了解函数的输入和输出
- 从部署、发布、监控 "一条龙" 式的平台服务,也较好的规避了常规的稳定性问题
3. 酷家乐 Faas 平台的落地方式
3.1 faas 基础设施
经过对各 faas 技术栈的分析比对,我们最终选择使用 K8s + Knative + Istio 的组合方式来搭建应用级 Serverless
上图是酷家乐现有的 serverless 架构切面,简单可以分为 用户层 和 平台层。
用户层:
- 通过 serverless-cli 来完成本地创建、开发、调试、发布等用户操作
- serverless 管理平台集成了实时日志查看、全链路查询等实用功能,并提供了一些页面式函数操作
平台层:
- 主网关、faas网关 做请求转发,再由 knative 网关转发到函数
- Built-in 是虚拟的一层,表示 image 的功能属性
- Runtime 是各语言栈的函数运行时,目前使用的主要是 node.js
- Knative 和 k8s,底层资源编排
3.2 faas 前台架构
这是酷家乐 faas 前台的整体架构,虚线框内是 函数构建&部署 流程。
对于企业而言,使用内部现有的 gitlab 托管函数代码、基于 gitlab ci 来控制流程是最简单通用、成本最低的管理手段,
由于 构建&部署 操作常常会随着集群信息、发布逻辑等改变而改变,如果让用户经常去更新代码仓库是体验非常差的行为,
我们把 ci 过程脚本、Dockerfile 等公用文件,都使用 oss 来托管;每次执行 ci 流程时,都会下载这些文件的最新版本,并根据 ci stages 步骤按需执行。
这样的话,我们每次的部署逻辑更新都会对用户无感。
3.3 faas 研发流程
与传统研发模式相比,faas 模式下除去了技术选型、资源申请等繁琐的流程,让用户更专注于业务逻辑上。
3.4 faas 产品介绍
酷家乐目前支持 node.js、python、java 的 faas 开发语言,下面简单介绍一下基于社区开源方案自研的 node.js faas 产品。
上一节有提到,我们使用 gitlab repo 来托管函数代码,repo 和 function 的关系是 1 :1,以此保证每个函数之间的彼此独立。
但是在业务推进中发现,真实业务场景这类独立逻辑并没有那么多,往往是需要写多个函数来完成一个 功能/需求。
通过对用户场景的具体分析,同时借鉴了社区开源 faas 框架的设计思想,我们引入了多函数的承载概念,将 repo 和 function 升级成 1 :n 的关系,这样就能把一整套逻辑的代码都聚合在同个 repo 里。
函数部署方式也可以根据实际场景去选择,多函数模式支持 独立部署、聚合部署、混合部署 三种方式。
比如聚合部署(即 pod 内聚合多个函数)适合处理低流量多接口业务、混合部署(聚合 + 部分函数独立部署)适合解决热点问题。
在函数编写格式和用户体验上,我们保持与社区、大部分云服务商的基本一致,便于后续可能的迁移和升级。
用户通过 faas.yml 配置来声明函数路由信息,并按需自由定义 接口路由、部署配置、公共插件等信息。
4. 酷家乐 Faas 平台的落地场景
目前酷家乐已落地 40+ 函数在线服务,但主要集中在 创新、边缘业务。
在已落地的应用场景上,主要可以分为有两类:
- 提供在线的,以 API 为管理维度的聚合类 API
- 提供离线的,以响应式和弹性为特点的离线计算业务
在开发语言上,Node.js 的使用率占多数,这也从侧面表现出 faas 对于前台服务的适用性和友好度。
5. Faas 和传统应用之间的思考
Faas 在发展中必定会考虑的一件事,就是如何衡量 函数 和 应用 的关系。
从当前发展趋势上看,无论云商还是企业内部、serverless component(也有用 faas 做载体的) 或是 faas 平台,都想利用 fass 带来的红利去实现应用级别的业务。
毕竟应用代表着用户量、业务规模、流量等等,某种意义上是一种革命成功的象征。但是没有一门技术是完美的,我们需要客观地看待 faas 对于传统业务应用的意义。
以前在一篇描述 “分布式单体” 的文章中看到过:
从 传统单体应用 到 分布式微服务,再到现在的 Serverless... 不过是建立在业务拆分的基础上,用 “进程间的远程调用” 简单替代了“原来进程内的方法调用” 而已。在本质上,Serverless 也并没有改变微服务中存在的内部耦合问题,只是更细化的组件粒度,却增多了系统中远程调用的数量。
而且对于大部分应用来说,faas 本身并没有太大的资源优势,虽然单个函数本身在资源占用上很小,但是由微服务拆分出来的函数服务,其需要引入的共享类库和网络客户端的规模是由 函数个数 * pod 数 决定的,资源消耗可能会远大于单个微服务的应用。
所以在需求落地前,我们要结合 “业务规模 和 faas 现状”、“资源成本 和 人力成本”、“跨组合作 和 快速启动”、“出错成本 和 容错粒度” 等因素来综合考虑是否选择 faas,而不是一股脑的上就行。
6. 未来酷家乐 Faas 实践方向
相信很多前端开发者都听说过这两个名词:
BFF (Backend For Frontend) ,服务于前端的后端。
SFF (Severless For Frontend) ,Serverless 化的 BFF 架构。
我们也很认可 SFF 能给酷家乐带来的业务价值,让更多的前端同学只需要关注于业务逻辑,就可以完成 API 的编写,发布和上线,实现数据适配层的自管理,减少前后端沟通成本,提高整体研发效率。
这个对于中小型开发团队来说的确是一个不错的选择,未来我们也将会在 SFF 上做更多的场景落地和架构升级,更好、更便利的赋能给我们的内部业务方。