查看原文
其他

微保Serverless实践之架构演进

cluo 微保技术 2020-10-20

作者:cluo 罗超

编辑:lynnewei 魏琳

微保前端架构在业务发展中根据业务、团队、开发等实际情况进行调整,不断进化。本文将具体介绍前端架构的演进过程及相关的思考。

1

架构v1

早期,团队使用经典的前后分离的架构,前端开发与后端开发通过接口进行合作。合作流程如下图所示:

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

1、前后端开发解耦

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

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

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

  3. 利于前端组件化与后端微服务化架构。

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

2、部署解耦

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

  2. 更加快捷的CI/CD,前端的编译过程可以非常简单地接入CI/CD 在前后端耦合的时代,前后端的统一部署相互依赖,分开部署后,可以针对前端项目以gitlab的repo级别来做相应的CI/CD。

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

1、前后端协作耦合慢慢成为开发效率提升的瓶颈,如下图所示:

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

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

2、页面渲染效率较差,如下图所示:

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

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

2

架构v2

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

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

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

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

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

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

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

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

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

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

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

2、App级别的部署与发布

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

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

3

架构v3

基于上面的这些限制,我们在前端引入云函数,架构进一步调整。调整后的角色合作流程示意图,如下:

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

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

1、自动扩缩容

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

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

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

3、按需收费

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

4、简单的运维管理

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

总体架构如下图:

4

结语

每一次架构的调整,我们都致力于让各种研发角色的职责更为单一、内聚,角色间更加解耦。但这种调整也需要有配套的工具,其中的trade-off需要根据短期成本和长期利益来衡量。架构不是一蹴而就的,而是逐步演化的。


 


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存