微保的 Serverless 云函数实践之路

作者:
发布于: 2020-9-28
归档于:

标签:Serverless架构设计

背景

微保前端架构在业务发展中,根据业务、团队、开发等实际情况,不断进化调整。本文将具体介绍微保前端的架构演进过程,以及团队最终选择使用腾讯云 Serverless 技术支撑前端架构的原因。

微保团队使用 Serverless 技术的主要应用场景:

  1. 前端开发同学,应用在BFF层,目前接入的有小程序,H5 页面。
  2. 数据组同学,面向的风控和推荐算法应用,做计算使用。

微保架构 v1

早期,团队使用经典的前后分离架构,前端开发与后端开发通过接口进行合作。

合作流程如下图所示:

毫无疑问,前后端分离的架构有比较显著的优势:

1. 前后端开发解耦

  • 前端与后端开发并行,缩短需求整体开发周期

  • 角色分工明确,线上问题定位与修复更加清晰

前后端分别设计与实现自己的错误监控和告警系统,前端对页面脚本错误进行捕获,上报至日志平台,经过日志处理工具,设置告警机制,将错误信息推送至相应的开发人员。

  • 利于前端组件化与后端微服务化架构

前后端分离后,前端可以使用更为便捷的框架以及基于这些框架的基础UI组件,大大提升开发效率。另外,前端开发也会基于业务的特点,提取业务专属的公共组件,所有组件化的沉淀,都是对生产效率的提升。

2. 部署解耦

  • 前端静态文件单独部署 CDN

前端项目中有大量的静态文件,包括 html、css、js、图片、视频等,将这些文件部署在 CDN 上,充分利用现有云服务的CDN能力,既能提升资源访问的速度又能保证资源访问的稳定性,尤其是在高并发的场景下。

  • 更加快捷的 CI/CD ,前端的编译过程可以非常简单地接入 CI/CD

在前后端耦合的时代,前后端的统一部署相互依赖,分开部署后,可以针对前端项目以gitlab的repo 级别来做相应的 CI/CD。

然而, 前后分离的架构对于业务早期的快速发展非常有效,而且在团队规模较小的时候,前后端开发人员合作固定,彼此对于对方的开发习惯、性格较熟,因此跨角色沟通的问题并不突出。但随着团队规模和业务规模持续扩大,这个架构模式给团队带来的副作用慢慢浮出水面。实践中,遇到的几个比较明显的问题,如下:

1. 前后端协作耦合慢慢成为开发效率提升的瓶颈。

如下图所示:

团队规模与业务规模的扩大,意味着合作的人员变多、接口的复杂度也会相应增加。

早期专人专项大家彼此的开发习惯也熟悉,对业务也都比较熟悉,因此业务接口参数的调整沟通成本较低。但随着业务规模和团队成员扩充,在各种跨业务合作时就会有人碰到不习惯阅读proto,或有些复杂业务需要花费大量时间阅读proto文档,或前后端反复沟通接口调用时参数的具体含义等问题。

2. 页面渲染效率较差

如下图所示

以产品详情页为例,页面的渲染需要请求至少5个后端接口,然后再对数据进行组装和处理。这不仅增加了小程序端的代码体积,页面渲染的速度也是被拉低了。

即使在前端页面对接口进行并行访问,但数据的整合逻辑依然会非常复杂。小程序作为微保主要的产品承载形态,代码量巨大,几近达到微信规定的代码上限,这种对于代码的增加随着业务增长也是一个隐形的风险。

微保架构 v2

鉴于上述前后端合作模式中的痛点,团队对架构再次进行优化,原则是业务“前”移、核心下沉。在前期的各种业务支撑中,团队已经有了一些业务中台的沉淀,比如投保服务、续保服务、保单服务等。

中间层的引入让团队的开发效率进一步得到提升,前端对于业务的把控力及页面性能优化的操作空间也大大加强。不管是从团队的敏捷性、还是应用的体验,都有不错的改善,比如以下几个方面:

1. 前后端流程上的耦合大大减小,角色责任的专一性逐步形成

基于一部分后端服务能力的积累,比如保单相关的需求,在需求评审及开发过程中,只需要前端开发同学参加即可。前端开发同学与业务产品沟通业务逻辑,在api市场或服务文档查询相应的服务能力,完成业务开发。同时对于团队逐步开展业务中台化、前端组件化大有助益,整个架构对于丰富多变的业务需求的响应更敏捷。

2. 渲染层对后端的服务进行聚合,减少页面请求

不管是H5网页还是小程序页面,均只需跟中间层打交道,前端开发人员根据业务的诉求,自行对接口进行聚合,端上只需要1个请求就可以开始渲染页面。接口聚合之前,产品详情页面的显示需要请求5个接口,平均的接口请求耗时为120ms左右,聚合后,通过中间层来请求5个内网接口,避免端与服务的多次连接耗时。

3. 中间层对数据进行加工,大大减少小程序端的逻辑代码量

之前在小程序端的数据整合代码,有些复杂的逻辑,可以交给中间层处理,这些代码的节省对于业务持续增长时会越来越体现出价值。以年金产品详情页为例,数据在中间层聚合能够节省10KB的体积。

中间层的引入是对生产力的进一步解放,但基于一个巨型 app 的 node 中间层,在后期的运维中也暴露出一些问题。中间层的应用部署在2台CVM机器上,有其先天的一些不足:

1. 应对尖峰流量的冲击能力差

微保经常会有一些运营和投放需求,这些事件都会导致瞬间的大流量打入,CVM的扩容相对滞后。

2. App级别的部署与发布

中间层不断积累业务代码,整个应用线性增长,每次部署与发布都是巨石应用的发布,部署效率低、风险高。

3. 前端开发人员在开发、测试环境中需要自己在机器上查阅日志和服务操作,提高了普及的门槛。

微保架构 v3

基于上面的这些限制,团队开始关注新的技术,加州大学伯克利分校计算机科学 Riselab 团队的实验室研究室提出:Serverless 是云计算的下一个浪潮。国内各大厂商也都开始布局 Serverless ,腾讯云 Serverless 团队是国内比较早在这方面进行部署的团队,技术已经非常成熟,在新东方、蘑菇街、哔哩哔哩、TP-link 等数百家企业成功落地实践。

通过调研了解到腾讯云 Serverless 云函数的优势:

  • 强大的扩所容能力,特别适合应对流量洪峰,且性能稳定。
  • 每个函数都是单独运行、单独部署、单独伸缩的,用户上传代码后即可自动部署,提升了独立开发和迭代的速度。
  • 云函数提供精细的日志记录,可方便地查看函数的运行状况,并对代码进行调试、测试和审计;支持相关的监控指标上报,能快速了解函数的整体运行概况,也可自定义云函数的监控指标。
  • 精确到 1ms 计费规则,只对正在运行的函数计费。

综上,基本解决了架构 v2 中面临的问题,可以说是省时省力。经过团队整体评估,我们决定使用腾讯云 Serverless 云函数进行架构的进一步调整。调整后的角色合作流程示意图,如下:

C 端的请求发至云函数 API 网关,网关转发请求至相应的云函数实例,云函数再向后请求服务的网关。整个链条上最大的变化是将云函数取代了node app,成为中间层的技术形态。

使用云函数替换掉 node app,背后的考量有以下几方面,也基本是针对 node app 实践中遇到的一些问题去加以解决:

1. 自动扩缩容

开发者不需要专门去配置,云函数可以自己根据请求量在函数层级水平扩展,正常情况下,一个空的云函数(运行时间 50 ms),300 个并发,压测可以达到 6000+ 的 qps,应对日常的高并发需求基本没什么问题。

2. 函数级别的开发与部署

一个云函数对应一个 gitlab 的项目,函数开发与发布都是围绕单个项目进行 CI/CD,高效、安全。

3. 按需收费

对于金融模式下的流量特点,大部分情况下请求量较少,云函数的使用可以避免稳定的资源投入,空闲情况下费用大大减少。

4. 简单的运维管理

开发者不需要在服务器上自己维护服务和查阅日志,通过云函数的配套工具轻松管理函数、查阅日志,也可以根据自己的诉求设置告警机制。

微保使用 Serverless 技术的总体架构

微保每一次架构的调整,都致力于让各种研发角色的职责更为单一、内聚,角色间更加解耦。但这种调整也需要有配套的工具,其中的 trade-off 需要根据短期成本和长期利益来衡量。腾讯云Servelrss 云函数很好的支持了本次架构的重新调整。

落地中的问题和解决办法

使用腾讯云 Serverless 过程中也不免遇到问题。

例如,公司有自建 es 集群,所有日志都会放在es里面,但是云函数的日志无法直接放入我们es里面,只能存入腾讯云的 cls,这个对于我们后期日志分析, 告警都不好处理。通过调研腾讯云cls, 发现里面有个挺好用的功能,可以日志投递到 kafka,在通过监听 kafka,我们将日志成功存入我们的 es, 且时延保证在秒级。

另一个日志规范问题, 日志的规范关乎后期日志分析、告警, 但是实际处理中发现日志的元数据信息较少, 比如我们有版本 tag,云函数绑定了 cmdb 相关信息,这些都希望在日志中打印出来, 后面我们发现云函数有个别名字段。我们在云函数中发现一个别名字段, 通过扩展了一下这个字段,填入了更多信息, 例如版本、cmdb 相关信息,这样在日志里面相关信息也会体现出来。

关于使用腾讯云 Serverless 技术在风控和推荐算法应用的介绍会在之后的文章为大家详细展开,敬请期待!




欢迎访问:Serverless 中文网,您可以在 最佳实践 里体验更多关于 Serverless 应用的开发!