写点什么

有赞移动基础设施建设的实践和思考

2020 年 3 月 15 日

有赞移动基础设施建设的实践和思考

移动基础设施的建设已经不用再过多解释,每个涉及移动开发的企业都在一步一步地建设移动基础设施,目标是为了服务移动团队,提供移动开发全流程的技术支撑,减少研发成本、提升开发效率、保障稳定质量。


有赞,是一个商家服务公司。我们帮助每一位重视产品和服务的商家私有化顾客资产、拓展互联网客群、提高经营效率,全面助力商家成功。随着近些年来业务的快速发展,移动领域功能越来越复杂,迭代速度越来越快,我们在移动基础设施方面的建设日益完善。


12 月 7 日,有赞移动技术沙龙向大家介绍了在移动基础建设方面的成果,到场的小伙伴们也十分热情。这里对有赞移动基础建设做一个系统的介绍,也分享一下我们的思考。


下图是目前有赞移动的整体架构图,现在每天需要经历上百次构建,每周迭代一个版本,在流程、动态化、效率、质量、合作等方面都越来越重要。而本来作为移动开发的我们,也逐渐具备了基本的前后端能力、运维能力。



一、流程


协作人员的增多,只有一起遵守流程才能更好协同。而这些流程不能停留在约定上,需要落实到系统里,通过系统来控制。实际工作中,有很多流程都可以进行落地,这里主要介绍一下发版前的上车机制、权限与审批流程等。


1.1 发版前的上车机制


每次发版前的上车机制,分支不能随便合,合分支都通过 Bus 平台进行提交,并确保符合条件(后端已发布、线上测试已通过、产品已确认等),并有人 Review,否则不予上车。而回归包验出的问题,需要提交代码的也需要在这个平台进行提交,保持透明,保持可回溯。如此,一方面很好地把控线上包的质量,另一方面也节省测试的回归时间。


另外,这个平台还做到了实时提醒和检测,减少不必要的繁琐的人工提醒、人工检查等机械式且容易忘记的动作。比如,当分支还没有被 Review 和 Merge 的时候,通知提交人;发车时间变更的时候通知到所有人等。



1.2 权限与审批流程


有赞移动有 Weex 发布平台、移动配置中心平台、App 分发平台、热修复平台等。这些平台都需要发布,而发布就需要规范化,需要审批制度。


我们抽象了一个模型,标准化了这些平台的权限和审批流程,现有的二方平台,以及将来更多二方平台都可以通过统一管理平台提供的接口接入,在统一管理平台上进行权限和审批流程的管理。


开发们可以很方便地申请权限、审批权限,会通过企业微信实时提醒(有的企业用钉钉也很方便可接入)。


详见之前发布的文章有赞移动关于权限与审批流程的标准化


二、动态化与跨平台


移动 App 开发相对于前端、后端来说,有两大天然差异:


  1. App 有版本的概念,每次新版本的升级迭代是有一个周期的;而前后端发布可以做到发布即全量;

  2. 发展到当前,App 剩下了两个阵营:Android 和 iOS,也就是说,原生开发条件下,一个功能需要开发两遍;而前后端则没有这个问题。这也是为什么,前端团队人数和移动团队人数差不多的情况下,前端团队完成项目数大致是移动团队的两倍。所以,动态化与跨平台一直是移动开发的两大主题。


2.1 Zan Weex 的建设


由此,各种跨平台框架不断冒出,从最初始的 Hybrid,到 RN、Weex,再到今年火热的 Flutter,都在努力去抹平端的差异性。


Hybrid 模式现在依然是普遍在采用的方案,不过受局限于 H5 页面的性能,所以才有了后面框架的用武之地。


有赞在 Weex 和 Flutter 都做了探索和尝试,现在移动团队平均每月超过一半的项目会使用 Weex 开发其中若干页面或者全部页面,而 Flutter 方面也做了一定的基础建设和线上页面的尝试,蓄势待发,还需要找到适合发挥它优势的场景。


ZanWeex 的建设一方面做到跨平台,还有一方面就是做到了页面级的动态化,支持修改、新增页面。


我们从开发(脚手架和 ZanWeex SDK)、构建( ZanWeex 构建平台)、发布与热部署(ZanWeex 发布平台)、监控等做了一整套建设,进一步降低了开发和部署 Weex 的门槛,并做到质量保障。


举个很小的例子,在 使用 vue 写页面时,原始的方式是:


<imageclass="logo"src="https://img.yzcdn.cn/public_files/2018/10/12/1151d58514efbc645ea266610ad8b743.png"/>
复制代码


这种方式,每次都需要先单独上传图片到 CDN,然后将 image url copy 到代码里。


在我们进行优化后,变成了下面的方式,只要将图片放置在工程目录下,然后使用相对地址即可:


<imageclass="logo"src="resources/phone/stock/people.jpg"/>
复制代码


实现大致原理:构建的时候,会将图片资源一起随着 js 文件上传到 CDN,然后在 ZanWeex SDK 里对图片的渲染进行拦截,对 URL 进行重构,定位到 CDN 上对应的资源,即可完成正常的图片渲染。


像这种小细节,我们做了很多,有兴趣可以交流。


Zan Weex 基础建设目前做到了三点效果:


  1. 为日常开发降低了接近一半的人力,这里之所以说的接近一半,是考虑了Native 与 JS 交互的部分,而这部分会越来越少,越来越简单,我们提供了一套常用的Module协议和组件库。

  2. 支持动态性,随时发布和回滚,发布支持灰度、条件、全量等。

  3. 开发过程中,还没有遇到迈不过去的致命的坎。


那么什么情况下使用 Weex 开发?会从以下几点考虑:


  1. 如果是新页面,只要交互不复杂,比如只是展示类的、或者单个列表式、简单表达式等,采用 Weex 开发

  2. 如果是老页面,UI 改版较大,又符合条件(1)的话,会考虑使用 Weex 重写


2.2 App 配置中心


App 配置


这种场景很多,本质上就是提供一个通用的 API,不用每个需要配置的地方,都由后端提供一个接口。可以抽象成 K-V 形式的,都可以通过 App 配置中心来完成。


比如一些新功能的开关、一些可能会变更的文案、一些可能会变更的数字等。


同样,下发使用灰度服务,支持灰度、条件和全量。


我们抽出一个通用的服务,用于支持灰度、条件发布,包括后面的App发布、热修复发布。


三、效率和质量


效率和质量,不能只看单一维度。效率提升的前提需要保证质量;而保证质量的同时,不是牺牲太大的效率。像持续集成、日志监控都在效率和质量方面同时做了贡献。


3.1 持续集成


持续集成就是为效率和质量而生。


移动的持续集成,在业界最常用的是 Jenkins,部署方便,无需更多开发,只要配置一下就可以。


我们考虑到扩展性,在 Gitlab Runner 的基础上构建了有赞移动的构建平台 MBD。



其中,Gitlab Runner 部署在 macOS 上自己管理,前端后端服务跟公司内部其他前后端一样统一管理。


在 MBD 上,支持 Android 的测试包、线上包、热修复,支持 iOS 的企业包、Release 包,支持 Weex 构建和 Flutter 构建,从提交、入队、构建(包括构建脚本)、上传等流程中都可以充分自定义,并做好数据统计,优化每个环节,优化交互体验,提升效率,服务好移动的开发和测试。


构建完成后,我们将构建结果同步给分发平台 APUB,通过 APUB 平台进行分发,提供友好的操作 UI。


关于线上包,Android 支持灰度、条件、全量发布。这里的灰度和条件,与 前面的 Weex 发布,使用的同一个服务;而 iOS 的灰度目前使用 App Store 自身的灰度机制。


关于热修复,Android 的热修复集成了微信的 Tinker,iOS 的热修复基于 Lua 实现,暂不支持 Class 类型和 selector 类型。同样,下发热修复包也支持灰度、条件和全量,使用前面提到的同一个服务。


3.2 日志监控


对于监控,是必须要做的,否则根本不知道在用户方发生了什么,所以需要日志,包括网络日志、操作日志、业务日志、错误日志等。日志平台的建设,也是同时为效率和质量服务的。这里的效率指的是排查问题的效率,质量是线上问题的监控。如果要存储这些日志需要大量的存储空间,而且大部分是无用的。所以我们采用了按需上传。首先将日志记录在本地,然后有三种场景会上传日志:


  1. 远程触发通知上传

  2. 用户主动上传

  3. 有error级别的时候上传



我们的日志平台可以很方便的搜索日志、触发上传日志,为排查问题带来极大的便利。


3.2 测试自动化


另外,在代码覆盖率、UI 自动化测试方面也做了一些探索和实践,这两方面更多的还是借用业界开源的工具。其中代码覆盖率,Android 基于 JACOCO,iOS 基于 LCOV。


四、合作


合作分为与外部的的合作和移动内部小组间的合作。之所以合作可能会是问题,大部分是合作边界不明确,合作内容不透明。这里主要介绍一下与后端的合作和移动小组间的合作。当然移动开发跟测试的合作、跟产品、设计等角色的合作,都可以做一些事情,落地成流程、工具或者系统。


4.1 接口胶水层


在与后端合作方面,一直有个痛点:后端是按业务域来划分的,比如店铺域、商品域、账号域等,但是 App 是一个集合体,每个页面需要的接口数据可能来自多个领域,这个时候由哪个业务域来聚合数据都不大合适。于是就有了胶水层,我们内部称作移动网关,由移动团队负责。从下图可以看出移动网关在后端架构里的位置和所做的事情。



如此,各领域的后端同学只要提供他们的 dubbo 服务,由移动开发在胶水层聚合、转发。这样有几个好处:


  1. 告别了每次都要讨论这个聚合接口由哪边来开发的问题

  2. 移动开发有机会多去了解后端的结构,了解数据的来源。移动开发很普遍的局限在于不了解后端,而业务逻辑又大部分在后端,从而导致不了解整体业务。这样很被动,无法对一个需求给出整体的解决方案。

  3. 提供给 App 的接口可以统一管理、监控,对排查问题、容错都有很大的帮助。


移动团队负责这个胶水层之后,不仅和后端同学更好合作了,自身也跨出了舒适区,“向前一步,海阔天空”。


之前有小伙伴对于移动开发如何入门后端也做了总结移动开发者的后端开发入门体验


4.2 共享组件


移动内部各小组之间的合作,主要体现在共用和共建。


像 UI 组件库就是个很好的例子。另外像网络、埋点、图片、账号等都保持一份基础库。


这种基础库的共用,为业务组件库的共用奠定了基础。否则,如果基础库不统一,那么当业务组件库需要复用的时候,一个 App 集成的时候就很容易引用了两套同样功能的不同基础库。


这种共用的基础库都有固定的 Owner,当需要完善而 Owner 又没有时间的时候,允许使用方提交 MR,然后由 Owner Review 和 Merge。


由此,有赞移动建设了门户站点,用于登记、搜索所有的组件库,可以很方便地找到目前是否已有这样的组件库,并且获知组件库的 Owner、仓库和 ReadMe。


五、思考


在企业规模不那么大、历史没那么久的时候,移动基础设施方面确实有很多方面可以做。


移动开发的全生命周期,从设计、编码、静态扫描、编译、构建、测试、发布、运维、运营等,各个环节都可以做很多事情。另外,移动中间件也越来越丰富,一开始的网络、图片、埋点这种必备的中间件,后续 HTTPDNS、热修复、消息推送进一步完善了 App 的体验,以及最近几年增加的人脸识别、语音识别、图片识别、智能客服、直播等等。还有跨平台框架里的 Webview 容器、Weex 容器、Flutter 容器,研发规范、测试、运维等,这里的每一项都可以做很多工作。


这么多事情,对于中小企业来讲,不可能在每一点都做的十分完善。那么在什么时候做哪一件事,就取决于自身企业所处的阶段、当前需要和长期规划。


随着中台概念的火热,移动中台的概念应运而生。而在这方面,阿里已经把它商业化,做成了面向企业的 EMAS 平台,包含了一站式移动研发平台、测试 &监控、用户运营、研发支撑等。而对于中小企业来讲,可以选择依靠这样的平台,也可以选择自己建设。而我们选择了自己建设。在建设的过程中,不断地激发自己思考,拓宽技术栈,了解业界情况,不断地遇见问题,解决问题,对于我们来说是一个不断成长的过程。


2020 年 3 月 15 日 20:19488

评论

发布
暂无评论
发现更多内容

深入浅出SpringMVC系列~

程序员的时光

spring springmvc

小岑的架构学习笔记-架构设计的历史背景

程序员小岑

你没必要活的那么累

小天同学

深度思考 个人成长 生活 成长 感悟

乙己说:NUMA是个啥?

再见小飞侠

jdk G1 ZGC 内存

[从零学习Spring Cloud]Nacos配置中心

玏佾

Spring Cloud nacos

实战!我用 Wireshark 让你 “看得见“ TCP

小林coding

Linux TCP 计算机网络

我的事务为什么会失效

JFound

spring

程序员的晚餐 | 5 月 21 日 四季豆炒腊肠

清远

美食

【迁移】CQRS很难吗?(译文:底部有原文地址)

罗琦

领域驱动设计 DDD

科学理论的反思

美多丽可

学习

Python 如何随机打乱列表(List)排序

Young先生

Python List random 随机

语雀性感,印象迟暮。

彭宏豪95

学习 工具 在线办公

数据产品经理实战-开篇

第519区

产品经理

分布式数据库

Leiy

小岑的架构学习笔记-架构是什么?

程序员小岑

传统岗位新挑战:信息安全之路

nexpose

安全架构师 安全 安全管理

乙己说:LRU实现思路整理

再见小飞侠

golang 缓存 LeetCode

怎么用"设计思维"思考产品?

Yanel 说敏捷产品

产品 设计 产品设计 产品开发

两边夹的应用三

孙苏勇

算法 两边夹

Review week1: Amazon的领导力法则

猫吃小怪兽

学习 高效工作 程序员 个人成长

Golang testing: “no test files”

北纬32°

golang

要弄清楚if/switch的本质区别,以及优化方式

张驰

Java

python 实现·十大排序算法之选择排序(Selection Sort)

南风以南

Python 排序算法

Android | Tangram动态页面之路(六)数据分离

哈利迪

android

高内聚与低耦合

落英亭郎

面向对象 高内聚 低耦合

图文并茂讲述如何正确的使用缓存

后端学长

缓存 后端 缓存穿透 缓存击穿 缓存雪崩

Spring注入的对象到底是什么类型

JFound

spring

码农理财(二)

北漂码农有话说

极客时间的三种身份:碎片整合的大师、成长焦虑的救星、工作技能的提升站

大橘栗

写给产品经理的信(1):产品经理的经济基础逻辑思维能力

夜来妖

产品经理 产品设计 职业规划 逻辑思维 工作

ARTS 第 51 周

马克图布

ARTS 打卡计划

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

有赞移动基础设施建设的实践和思考-InfoQ