以下内容取自「2020 小程序云开发技术峰会 -《小程序云开发的持续交付和质量管控》」主题分享,演讲嘉宾:张洪晖,微信支付高级前端工程师,与大家分享高速发展的业务团队如何利用小程序云开发搞定持续交付和质量管控。
01.
云开发的「老朋友」
首先来看一下小程序的发展规模。根据微信发布的 2019 年度报告,小程序在当年带动了 536 万就业,对社会的贡献非常大,更可观的是它的同比增长达到了 195%,可以看到小程序生态发展地非常迅猛。
我所在的团队是微信支付境外团队,团队出品的境外游礼包项目的重要载体之一就是小程序,它可以支持用户到全世界各地都可以获取我们的汇率优惠和优惠券以及礼包优惠。
作为第一批使用云开发的团队,称得上是云开发的“老朋友”。总的来说,从传统的小程序开发模式,切换到云开发模式之后,我们的产出率增长了将近三倍。
大家可能会有疑问,为什么在切换到云开发模式后,产出率会增长这么多?要回答这个问题,先来看一下传统的开发模式是怎样的。
02.
开发模式对比
传统的开发模式中,前端需要负责小程序的 UI 以及逻辑构建,由后端来实现 CGI 和后端服务,而产品经理提需求,需要给前端同学提一遍需求,同时也要给后端同学同步需求,这里就增加了沟通成本。
需求定下来之后,前端和后端的同学是需要进行沟通协作的,这里也存在一定的沟通成本,另外由于后台服务非常注重稳定性,需要做好风险把控,所以灰度流程会比较长。
上述的种种情况对团队的开发效率存在一定影响,而在切到云开发模式之后,我们的开发流程被大大简化了:
后端同学只需要关注后台的服务,而 CGI 这一层完全由云函数 SCF 去进行承担,大部分场景下,产品需求只需要一个前端同学就可以完成了。另外,由于前端同学做全栈的开发,也省去了协商沟通的成本。
这对后端同学也是非常有益的,目前在这种模式下,后端同学可以更关注于服务的稳定性以及提供一些能力,让运营的玩法需求全部交给前端同学去做。
03.
团队应用云开发的痛点
经过一年的高速发展,项目用户不断增多,团队不断壮大,项目中使用的云函数 SCF 的数量也不断在增加,让我们看到了一些隐患。
第一,项目发布没有审批。例如,在开发者工具上右键点击上传,查不到具体是由谁发布,这时也没有额外的审批环节,可能会导致发布错了之后难以溯源。
第二,云函数是相互独立的。为了一些逻辑的互用,会提供一些公共的代码,这些公共的代码是通过脚本下发的方式来下发各个云函数,这种方式有效提高了代码复用率,但是反过来,如果发布前忘记下发步骤,可能会导致代码残缺。
第三,我们的云函数的上传方式是在开发者工具里点击右键完成上传。由于项目云函数数量非常多,一个个点击和发布非常耗费时间,在十分顺利的情况下往往都需要两个多小时进行部署和确认。
总结来看,项目小程序的部署发布效率比较低,该如何去提升呢?此外,当流程较多时,需要注意的要点也非常多,该如何保证不出错呢?
04.
持续交付
这里团队就引入了持续交付的概念,得以让我们又好又快地使用云开发。
上图是持续交付流水线的总览。触发构建之后,通过手动触发的方式,进入二级的审批流程,接着我们会去仓库里面拉主代码,拉完代码之后,还会有一系列的代码检测和测试。
测试通过之后,才会去走小程序和云函数两条发布的流水线,发完之后会将版本发布的消息同步给大家。
看到这里,大家可能会有一个疑问:为什么要用手动触发这种方式呢?它的效率是不是很低?
确实,除了手动触发这种方式,其实还有 git hooks 这种自动触发的方式,它的效率相对来说会比较高。
关于这个问题,团队也进行了多维度的衡量与思考,结论是:自动触发方式更适合的场景是测试环境,因为它对稳定性的要求并没有那么高,但是它需要即时去同步一些新的特性,最终,我们在测试环境以及产品体验的环节使用了自动触发的方式,但真正对外进行发布的时候,我们会用手动触发的方式保证质量,并且会有二级审批的流程。
05.
高效部署
说到触发,上文讲到一个一个点击云函数的部署方式效率非常低,那么我们如何去做到高效地部署云函数呢?
首先,团队使用了云开发提供的 CloudBase-manager-node 等基础库,并基于此封装了获取云函数列表、部署单对云函数以及全量部署云函数等能力。
同时在小程序一侧,利用 miniprogram-ci 这一自动化部署能力,封装了自动上传代码包,优化了用开发者工具上传的步骤,但在发布之前,会提前去下发公共代码,以保证代码的完整性。
自动部署这种方式的效率非常高,用起来也非常爽,但如果发布引入了一些 bug,可能会出现很多严重的后果,因此在持续交付过程中我们还引入了灰度发布的能力。
06.
灰度发布
在初始化的时候,我们的小程序和云函数,会有小程序的新版本,云函数有两个环境:灰度环境和正式环境,现网的用户拿到了现网的小程序版本,我们可以放心的把一些新的云函数特性部署到灰度环境,把路径指到灰度环境。
当开始灰度时,我们会慢慢扩大灰度比例,把流量慢慢导入到灰度环境,同时现网的用户拿到旧版本的比例有一定程度的下降,团队也要看一下监控以及指标是否有问题,有问题的要快速进行回退。
当灰度完成的时候,现网所有的用户拿到的都是正式版本的小程序,这个版本是 100%流量访问灰度环境。刚才所谓的灰度环境,这时候就变成了正式环境,而正式环境就变成了灰度环境,也即完成了蓝绿发布的一个切换,当进行下一次进行发布的时候,就可以把新的特性部署到我们的灰度环境。
这种设计有非常大的优势,大家可以思考一下。第一,它控制了变更的风险,可以及时快速的进行回退;第二,客户端和云函数是一起进行灰度的,即使需要做一些破坏性变更,例如协议变更时,也完全不用担心线上的小程序版本是否兼容新的协议;第三是基于灰度设计的能力,适合做一些产品特性的快速验证。
有了整体灰度的能力之后,大家可能会问,是否有对云函数单独灰度的能力?当然,我们也设计了云函数单独灰度的能力。
可以看到,我们的小程序带着版本号过来访问,会请求到 getCloudEnv 这样的云函数,其实这个云函数没有做一些复杂的逻辑,只是单纯的去云 DB 里面去获取当前这个版本应该访问到哪个环境,这里就会对灰度的比例以及白名单用户进行一个判断。
当我们带着版本号返回到前端的时候,前端小程序就会根据这个版本号去访问到对应的灰度环境,团队也是基于此设计了云函数的单独灰度。
这里给大家看一下效果:下图中,纵轴是灰度比例,横轴是时间线,可以看到红色这条曲线是灰度比例,从 0 慢慢地放大到了 100%;而绿色这条曲线,当蓝绿发生切换的时候,流量从 100%慢慢下降到了 0。
除了用灰度发布来控制变更风险,还有很多质量检测的一些能力。比如说 Lint 检查,防止代码风格发生一些问题;自动化测试,来防止代码变更影响现网的功能;还有一些代码报告等。
最后,看一下持续交付的整体效果,在引入这条流水线和持续交互之后,代码顺利变更了 150 余次,有效支撑了产品的迭代。
另外,部署时间也从原来的两个小时缩短到了 5 分钟,这大大节省了研发的人力。此外,在引入流水线之后,实现代码变更 0 故障,让发布也更加安全。
07.
为什么需要质量管控
先来介绍一下金融业务下的质量难题,很多团队可能经常会遇到一些质量问题。大家可以思考一下,在不把控质量的情况下追求效率是否有实质性作用?
对于这个问题,以微信支付为例:微信支付是一个传统金融与互联网的结合。传统金融的稳定性要求比较高,一定程度上可以牺牲效率来换取稳定性,而互联网追求的就是效率,当质量和效率进行结合的时候,对团队要求是非常高的。
举个例子,我们团队小程序的发布节奏是平均每周一个版本,每天平均 新增800行代码、修改300行代码。业务压力来了之后,开发同学进行代码的变更时就涉及到质量管控问题,这反过来可能会影响效率。例如,在进行重构和代码的修修补补时,其他需求的涌入,会加大整个业务的压力,长此以往,很可能进入到一种负循环中。
那么,如何破局?常规思路下,业务压力大,首先想到就是通过增加人力来缓解业务压力,但由于每个人的代码风格不尽相同,人员增多也增加了代码的管控难度。而在重构方面,团队通过持续交付的流水线、重构抑制效率的损失,但反过来,也存在重构某些代码影响线上业务的风险。
由此,为了解决这个痛点,团队提出了非常重要的一点——质量管控。
08.
质量管控
下面重点介绍下团队是如何省心又省力地做好质量管控。
这是团队在优化质量管控前的情况,总体来说,流程分为需求、开发、发布和线上阶段。概括来说,可以分为事前、事中和事后三个阶段。
对于金融业务来说,这真的够了吗?事实上,以上流程存在一定的隐患,以小程序的底层架构为例,相信对小程序开发熟悉的同学非常了解,图中的逻辑层和渲染层是分离的,也即逻辑层无法拿到渲染层的结果,没有办法对渲染层进行监控。
假设在这种情况下,账单和资金展示出现了问题,一定会引起用户的投诉,那么,如何防范这种情况的发生?
首先,团队便想到做标准化的组件,其中最主要的就是金额渲染的组件,不单要做,还要考虑开发同学有没有真正用起来。为此,在开发流程当中,会对敏感字段进行一些扫描,来看一下组件是否有被正确的使用。
下图左侧是一个例子,我们通过关键字检测到这段代码没有正确使用金额渲染的组件,就立即停止了代码的提交。并且,为了增强检测的力度,团队也会在流水线中进行关键字的扫描。
静态金额渲染检查一定程度上解决了我们的问题,但是它足够安全吗?当然不是的。试想,如果关键词中的 money 拼错了,写成了 mnoey,是不是就被漏掉了?另外我们 UI 也有可能溢出,导致账单或资金展示出错的风险。
这里团队就引入了一个 UI 自动化截屏的方案,底层基于小程序开发者工具的 automator 的能力,实现自动地拉起开发者工具,并且跳转到对应的页面,然后对数量进行拦截(提前写好接口用例),在拦截之后,会对页面进行滚动截屏,截下来的图片会进行图片的比对并归档,在归档之后,还会通知产品和研发去进行审核。
举个例子,我们用一个命令启动了开发者工具,在开发者工具启动之后,会启动模拟器,模拟器会根据我们预设好的一个路径去跳转对应的页面,并自动进行滚动截屏。当我们截完所有的页面后,会在本地将这些图片保存下来,以供比对和归档。
左边是我们的旧截图,右边是我们的新截图,两个截屏之间进行对比,中间是对比,发现底部的优惠券区域有所变化:新增了小红点。由此我们就只需关心本次变更是否有影响到这一块逻辑,如果有的话,需要及时排查问题。
这里就是刚才讲到的质量管控的总体思路,是分为事前、事中和事后三个阶段进行。
09.
总结
最后,总结下团队为什么使用云开发,以及云开发到底给了我们什么样的能力?
1. 云开发给了前端同学一个全栈开发的能力,同时对后端同学也是非常受益的,让后端可以更关注业务的稳定性。
2. 云开发成本非常低,具体包括低开发成本,低开发门槛和零运维成本。
3. 团队非常看重云开发的生态能力,包括接入了微信支付、COS 和 redis 各种各样的能力套件,都支持开箱即用。
用上云开发之后,大家也可以思考一下是否有「用好」云开发呢?本次分享的内容主要集中在如何用云开发提升效能,包括持续构建、持续发布 ABTest 方面,而在质量方面,我们也会有灰度发布、自动化测试以及 UI 的自动截屏,另外,使用云开发的过程中也运用到了微信的私有链路,可以提供强大的安全防刷能力。无论路径如何,这些目标都是一样的,最终都是为了更好地支持我们业务的快速迭代以及小步快跑。
希望大家都能基于云开发这个研发平台,多思考,多尝试,站在云开发的“肩膀”去做出更多适用于自身业务的改良。
作者:张洪晖,微信支付高级前端工程师。
推荐阅读
One More Thing
立即体验腾讯云 Serverless Demo,获取 Serverless 新用户礼包,请在 PC 端访问:
serverless.cloud.tencent.com/start?c=wx20210425
欢迎进入千人 QQ 群 (871445853) 交流 Serverless!
- GitHub: github.com/serverless
- 官网: cloud.tencent.com/product/serverless-catalog
点击「阅读原文」,轻松体验 Serverless 应用部署!