最新发布《数智时代的AI人才粮仓模型解读白皮书(2024版)》,立即领取! 了解详情
写点什么

手机淘宝高质量持续交付探索之路

  • 2015-02-02
  • 本文字数:4638 字

    阅读完需:约 15 分钟

前言

随着移动互联网的迅速普及,手机淘宝业务在迅速的成长,目前已经发展成为拥有 40 多个 bundle(业务模块)的超大 APP 产品,在这后面有着数百名的研发人员的努力工作。业务的成长和人员的倍增给技术架构、团队合作、产品的交付都带来了巨大的挑战。本文将会讲述手机淘宝研发团队在两年的时间为了达到高质量持续交付的目标而做出的种种努力。希望借此机会向大家分享手淘的经验与教训,与大家共同探讨高质量持续交付之道。

第一阶段:单工程单构建产物、初级流程、初级质量保障

回到两年多以前,手淘还是一个年轻的产品,业务不多、研发人数不多、代码数量也不多、测试的手段也很单一。这个时期的特点就是所有代码都在一个工程里面,测试、发布都是围绕这一个工程的代码分支所编译出来的包来进行的。

工程架构

这个时候的手淘基本上就是一个大工程,依赖以源码依赖为主,所有的开发人员共享这一个工程,在同一个工程上开发。

存在的问题

  1. 代码混在一起,不便于管理。一个模块的代码有问题就会影响整个项目的开发人员。
  2. 不能支持业务的快速增长。

研发流程

工程的架构决定了研发交付的流程,所以当时的流程也比较简单,开发人员在本地开发完成以后直接提交代码,然后编译服务器进行打包,出包以后测试人员进行测试,如此反复,最根据代码库的最后一次提交进行发布。如下图所示:

存在的问题

  1. 提测和集成阶段混在一起,提测代码质量较差,开发人员不断的提交修改 bug 从而导致不断的集成包。
  2. 任何一个编译不过的问题会造成整个团队在等待。
  3. 回滚只能做到代码级别的回滚。
  4. 发布前回归如发现问题只能等待开发人员修改 bug,然后重新出包,再进行一轮回归,如此反复工作量很大。
  5. 如遇到阻塞问题,比如登录有问题,那么所有的人员都要等待登录的开发人员修改完 bug 才能继续工作,造成了大量的等待时间。
  6. 发布过程只有正式发布这一个步骤,很容易造成故障遗漏到线上。

质量保证手段

这个时期的手淘测试主要以手工测试为主,附加一些 monkey 测试和少量的自动化脚本。

存在的问题

  1. 纯手工的测试造成了测试人员大量的在做重复工作的现象。
  2. 测试经验没有积累。
  3. 非功能性的问题缺乏测试手段。
  4. 出集成包的节奏不可控,导致测试人员频繁换包测试,造成大量的重复工作。
  5. 对于不同的环境需要打出多种不同配置的测试包(如:测试包、预发包、线上包等),测试人员需要安装多个包进行反复的回归。

第二阶段:多工程单一构建产物、平台建立、初级持续集成、发布流程建立

随着移动互联网的迅猛发展,手机淘宝的业务随之倍增,研发人员也倍增。这个时候大小业务模块已经超过 20 个,研发人员超过了百人。这个时候原有的工程架构已经完全不能满足业务的需要了,质量保障也面临着很大的挑战,也就是在这个时期我们建立了一系列的平台:打包平台、发布平台、测试平台、验收平台从而使用自动化的方式提升了些效率。并且建立了灰度发布的流程,提升了最终发布的质量。不过这些努力也没有阻止质量和交付问题的大规模爆发……

工程架构

工程架构是整个研发的基础,所有的事情还是要从工程架构讲起。为了能够接入越来越多的业务,手机淘宝的架构从之前的单一工程的方式演进为模块化开发的方式,每一个模块被称作 bundle。同时引入了仓库的概念,每个模块将源码打包之后 deploy 进入仓库,然后由 builder 工程进行依赖管理并编译打包。

存在的问题

这次改造解决了之前多业务并行开发的问题,最终打包的时候也不会直接依赖各个 bundle 的代码库,完成了部分的解耦。但是还是存在很多的问题:

  1. 在同一个版本中所有的研发人员还是用的同一套依赖配置,任何模块的改动还是会影响其它模块,尤其是核心业务和框架层 SDK 的提交有问题的话会影响整个团队的进度。
  2. 仓库的版本管理混乱,开发和集成共用同一套仓库,开发可以随意部署,造成集成包无法控制。
  3. 由于各个 bundle 是将源码部署到仓库的,所以构建还是以源码为基础的,在代码越来越多的情况下,造成了整包编译速度缓慢。尤其是在等待很长时间以后编译失败,这种感觉是让人抓狂的。这个问题已经极大地影响到了研发的效率。
  4. 各个 bundle 的代码最终还是要编译到一个产物当中,各个 bundle 还是会相互影响,编译失败后定位问题成为了一大难题。

这里讲一下当时几个典型场景:

  1. 开发人员只是添加了一个方法,然后等待了 10 分钟进行编译,结果编译失败,然后排查一下午问题,结果是框架 SDK 更新导致的。
  2. 一大早几十个测试人员在等待回归验证发布包,结果发布包不是编译失败就是核心功能不可用最后到了凌晨 2 点钟,发布包终于出来了。

这样的场景太美,让人不敢去回忆。

研发流程

由于架构改造,提交集成的角色从开发人员变成了业务模块的研发团队,提交集成的方式从提交代码变成了 deploy 到仓库,但是由于工程架构的问题本质上没有完成各个 bundle 的解耦,所以整个团队还是在一条线上进行开发。不过这各阶段加入灰度发布的概念,灰度制度的建立使很多问题提前暴露,从而提高了正式发布版本的质量。

另外这个阶段建立起了代码审核、打包平台、发布平台、测试平台、舆情监控平台等,自动化了很多事情,在一定程度上提升了工作效率,大致使用流程如下:

存在的问题

  1. 集成的虽有雏形但依然不明显,提测和集成的界限依然模糊,很多 bundle 还是开发完以后直接 deploy 到主项目中然后打出集成包进行测试。
  2. 集成的标准虽然提出,但不能很好的运作,导致集成质量很差。
  3. 核心功能阻塞的问题越来越突出,长时间出不了可用的包成了一个大问题。
  4. 回滚操作依然困难。
  5. 项目的节奏依然混乱,导致项目延期和研发人员效率下降。

质量保证手段

这个时期的手淘测试团队建立了内存、性能、流量电量等专项测试机制,编写了一些半自动化的测试工具,建立了自动化适配平台,并组建了外包团队以提高测试覆盖率。这时候测试人员工作流程如下图:

存在的问题

  1. 测试人员在不断的更新测试包和等待出包上面浪费了大量的时间。
  2. 自动测试和专项测试只能在灰度阶段版本质量基本稳定的时候才能介入,这不但压缩了这些测试的时间,而且由于是在项目后期发现的问题所以会使问题修复成本增加。
  3. 非功能测试只有专项测试人员来做,此类测试的覆盖率还不理想。
  4. 测试经验的积累手段主要是自动化测试平台,但是这对于手淘研发团队来说还是远远不够的。
  5. 外包团队的组建解决了人力紧张的问题,但是外包人员的工作效果难以评估。
  6. 对于不同的环境需要打出多种不同配置的测试包(如:测试包、预发包、线上包等),测试人员需要安装多个包进行反复的回归测试。
当前阶段:多工程多构建产物、流程逐渐完善、多种质量保障手段建立

基于前两个阶段的经验和教训,手机淘宝研发团队在工程架构、研发流程、质量保障等多方面不断的进行完善,从而建立起来现在的体系。

工程架构

现在手机淘宝的工程架构进行了进一步的改造,形成了一套插件化的体系,而分 bundle 编译的引入大大缩短了构建时间,从而使构建速度不再成为瓶颈。另外分 bundle 编译可以提早发现编译问题,从而不会导致整包编译时编译失败。另外引入了依赖配置项的概念,目前项目完整包的构建完全取决于依赖配置,在单 bundle 开发、提测、项目集成、发布等各个阶段的依赖配置完全独立,各个 bundle 的开发测试人员可以在完全独立的环境中进行开发测试,不会受到干扰。

研发流程

有了工程架构的有力支持,研发流程慢慢进入了正轨。首先明确了 bundle 开发、提测、集成、灰度、正式发布等各个生命周期的边界,真正做到各个阶段的相互独立。其次在各个生命周期中加入了规范性的流程,并由平台保证了流程的真正实施。最后质量保证手段和效率也有了很大提升。基于以上几点手淘的整个研发做到了类似于火车发车的发布过程:

  1. 各个 bundle 在有着自己的需求、开发、测试计划,相互独立。
  2. 手机淘宝主项目制定发布计划,确定集成窗口和发布时间点。
  3. 在集成窗口时间 bundle 可以自主提交集成。
  4. 集成提交需要走流程,包括填写 checklist、代码检查、bug 统计、提前编译预集成包进行测试等。这就避免了明显的集成问题遗漏到集成环境中。
  5. 集成期间的集成包每天出一个或者两个,避免了测试人员不断拿包回归的情况。
  6. 集成窗口对于时间要求严格,赶不上计划或者质量不达标的 bundle 不予集成。这就是火车不等人的原则。
  7. 以上机制保证了手机淘宝每天都有一个候选包,可以随时进行灰度发布,并且灰度发布单独拉取一个依赖配置分支,不影响集成窗口。
  8. bundle 的独立,依赖配置的独立保证了手机淘宝可以并行多个发布计划,各个 bundle 可以按照需求自主决定搭乘哪个发布计划进行发布。
  9. 目前手淘项目节奏为两个星期发布一个版本。如果需要还可以更快的进行发版。最短只需要 1 个小时就可以发一个新版。

目前的平台建设工作也进入了快车道,所有的项目生命周期都有相应的平台工具支持,如下图:

质量保证手段

有了高效稳定的流程,剩下的事情就是如何保证产品在快节奏的持续交付下的保持很高的质量。质量保障上面手机淘宝研发团队做了几方面事情:

1. 流程方面

1)创建了提测单、集成单、发布单等流程。建立了标准,并依托平台自动检查,提高了交付的质量。

2)建立持续集成体系,不但能提早发现更多的问题,而且提升了测试人员拿到的包的质量。

3)建立线上线下监控分析体系。

2. 包稳定性方面:

1)bundle 阶段根据项目进度自己控制提测包的频率,集成阶段每日验证 DailyBuild 即可,所以解决了之前测试同学不断安装新版本的包的问题。

2)研发阶段的包内部支持环境切换,这实现了只构建一次,环境根据配置切换的梦想。测试时手机上只需要安装一次包即可完成多种环境下的测试。

3. 自动化测试与测试工具方面

1)引入多种静态扫描引擎,并定制多种规则:适配规则、Crash 规则、框架约定规则、安全规则等,并且不断地将测试阶段、线上问题等总结抽象成新的扫描规则补充进入扫描引擎。

2)在测试阶段包种插入相应的测试 SDK,并且这种 SDK 不会侵入应用代码,所以只需要在发布的时候去掉测试 SDK 即可。测试 SDK 可以在测试人员(包括外包适配测试人员)正常使用过程中自动检测并上报问题,这样就可以在同一的平台上看到研发过程中的质量情况并进行修复。

3)自动化平台方面也在根据手淘测试经验不断的进化,在整个研发过程中自动化测试一直在执行,不仅可以提高产品稳定性,也可以发现性能、电量等非功能问题。

4)mock 工具、验证平台等辅助测试工具也提升了测试人员的效率。

4. 线上线下监控分析

1)线下质量数据、线上业务问题、舆情反馈等信息统一汇集到平台上进行统一的分析告警,不仅能快速的发现问题,而且能通过数据分析能够帮助快速定位和解决问题。

2)根据平台中的数据,可以用经验推动流程的优化、补充测试用例、添加扫描规则、增加自动化场景、催生新的测试工具等,这样可以使经验形成闭环,使质量保障工作更加高效。

以上就是手机淘宝研发团队在建立高质量持续交付体系过程中的经验分享,虽然现在在架构、流程,质量保障方面有了一些积累,但是在移动互联网这个领域还有诸如稳定性、电量、流量、性能、适配、用户体验、线上运维、故障告警等难题等待我们去解决。前方的道路依然坎坷,我们会更加努力,并不断前行。

作者简介

杨强(花名:元战)阿里巴巴技术专家,2012 年加入阿里巴巴无线事业部,目前负责手机淘宝专项测试组,主要负责无线研发支撑平台,无线技术运维平台,无线专项测试工具以及无线 SDK 测试等方面的工作。曾经在趋势科技、华为从事测试工作。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2015-02-02 14:469990

评论

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

一文教会你认识Vuex状态机

华为云开发者联盟

Vue 应用 vuex 事件 父子组件

面试官:如何给字符串设计索引?

一个优秀的废人

MySQL 索引 字符串 索引优化

Java 并发编程——线程池开篇

Antway

6月日更

构建高可用的MySQL

林一

MySQ MySQL 高可用 Maxscale

证券互动问答平台关键词监控提醒

木头

互动平台 证券监控 股市消息 监控提醒

如何针对美工与设计师的Maya工具进行版本控制

龙智—DevSecOps解决方案

博云作为专业独立PaaS厂商,入选中国PaaS市场研究报告

BoCloud博云

PaaS

待办事项列表,敏捷项目管理的核心工件

万事ONES

Scrum 敏捷 研发管理 ONES

质量分析工具-监控大厅大揭秘

anyRTC开发者

音视频 WebRTC sdk

想做DBA,多租户管理你一定要知道这些

华为云开发者联盟

多租户 GaussDB(DWS) 资源池 存储空间 资源隔离

react源码解析9.diff算法

全栈潇晨

react源码

Webpack 系列:如何编写loader

范文杰

webpack 6月日更

那个陪我打王者的兄弟进了阿里

艾小仙

小白必看的,JS中循环语句大集合

华为云开发者联盟

JavaScript js 循环语句 while循环 for循环

理解Linux之文件I/O——知其然,知其所以然

奔着腾讯去

文件管理 Linux内核 文件I/O I/O模型

带你剖析鸿蒙轻内核任务栈的源代码

华为云开发者联盟

鸿蒙 任务栈 任务调度 任务上下文

如何科学制定和管理项目计划?

万事ONES

项目管理 ONES 项目经理

☕️【Java技术之旅】带你一起探究String类不可变的特性

洛神灬殇

string 原理 字符串 6月日更

基于传感器的人体生命体征监控技术

不脱发的程序猿

物联网 传感器 智能医疗 人体生命体征监控技术

模块六作业

c

架构实战营

宜兴牵手百度智能云共建人工智能应用中心,推动数字经济创新发展

百度大脑

人工智能

如何进行可视化大屏视觉设计?

博文视点Broadview

百度灵医智惠明星案例获人民日报点赞:智慧医疗让看病更便捷

百度大脑

人工智能 智慧医疗

24道几乎必问的JVM面试题,我只会7道,你能答出几道?

北游学Java

Java 面试 JVM

【LeetCode】从上到下打印二叉树 Java题解

Albert

算法 LeetCode 6月日更

聊聊追求测试技术导致过度测试

陈磊@Criss

☕️【Java技术之旅】站在Linux操作系统角度去看Thread(线程)

洛神灬殇

线程 Thread 6月日更 内核线程

开发感想 基于8051的数据采集系统(科技向)

万里无云万里天

经验总结 6月日更

春色满园关不住,带你体验阿里云 Knative

阿里巴巴云原生

云原生

企业应用AI之路怎么走?飞桨实践有真知

百度大脑

AI 飞桨

内嵌双向链表的设计与实现

实力程序员

手机淘宝高质量持续交付探索之路_语言 & 开发_杨强_InfoQ精选文章