一、什么是持续交付
持续交付(Continuous delivery,缩写为 CD),是一种软件工程方法,让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定、持续的保持在随时可以发布的状况。它的目标在于让软件的编译、测试与发布变得更快更频繁。这种方式可以减少软件开发的成本与时间,减少风险。 而我对持续交付的一个较为抽象的理解是“一套软件工程方法论和许多最佳实践的集合”。方法论和实践都需要人去总结落地,所以,要想体会到持续交付的真正含义,就要在实际工作中贯彻和使用实践工具。
二、持续交付的价值
其最大的显性价值是,在实施持续交付后,能够做到在保证交付质量的前提下,加快交付速度,从而更快地得到市场反馈,推动产品的商业价值的实现。在互联网应用盛行、速度为王的几天,持续交付的价值更被突显出来。持续交付的能力,已成为评定一家互联网公司研发能力的重要指标。除显性价值外,如果站在不同角度看持续交付后的变化,我们还会发现一些隐性价值,而其中有一些影响甚至远远超过我们的预期。
1、通过快速灵活统一的环境构建,全面改善企业对测试环境的管理方法,使得环境管理更合理、更自由。
2、标准、规范、流程的落地,都需要载体,而最好的载体就是平台工具。而持续交付是一整套平台工具的落地,几乎涵盖了研发的整个生命周期,是天然的、最佳的载体。
3、持续交付能够向各个协作部门输出统一的标准、流程和工具,提升沟通效率;并且通过大量的自动化,进一步提升各部门工作效率;还可以快速集成,把各个分散的小团队,无论是横向的业务研发团队,还是纵向的技术框架团队,紧紧地联系在一起,共同进退。
4、生产故障永远是无法完全避免的,那么,解决生产故障的最好办法就是快速回退(回复),而快速回退正是持续交付着力打造的能力之一。
三、持续交付的落地
了解了持续交付的价值以后,我们再看持续交付在我们团队的具体推进实践。坦诚地说,在任何一个团队推行持续交付都不是易事。
- 首先这会影响整个的研发生命周期,会涉及到流程、团队、工具等多个方面,需要突破当前组织的束缚,引起大量的技术和组织变革。
- 其次大多数团队都希望能够快速见效,立竿见影。
但是,“持续交付”的改进过程本身就是一个持续迭代的过程,需要多次循环才能体现效果。甚至在实施初期,因为开发习惯和流程变化,团队在适应的过程中效率会有暂时的下降。
我们之所以开始做持续交付:
- 一方面是因为随着团队规模、体量的增大,比如我们应用数量达到了500 ,系统之间依赖度高,需要有平台化的交付系统来支撑大量业务上线,且通过交付平台去解决工程问题,解放业务研发人员的大脑,让他们可以专注于业务研发而不是工程问题,比如环境查看,部署等;
- 另一方面,团队也在做应用环境容器化,这也为持续交付提供了很好的支撑。
领导对此事非常重视,专门抽调运维、DBA、测试开发同事临时组建虚拟的效能研发团队,了解需求,分析各项目特点,封闭开发3个月的时间,打造出基础级的持续交付中系统,并以一个项目为试点,通过数据去说服同事对接进来。
四、持续交付四要素
从代码提交开始,我们可以把整个持续交付归纳出四个关键要素:持续集成、自动化测试、自动化部署、流水线。下面分别从四个关键要素解读我们的持续交付平台。
1、持续集成
将代码开发和集成按模块拆分成多个小阶段,每一阶段完成后都会进行集成,这在一定程度上减少了风险。 我们要求在代码提交时即触发编译。构建时会对整个应用的所有模块进行编译,并伴随单元测试以及代码质量分析。如果构建过程失败了,那么必须立即邮件告警到相关开发责任人,并责令立即修复问题,如果20分钟内无法修复,就要回退代码提交,总之,要求代码库的代码持续处于可用状态。 目前,每次成功的构建(编译 单元测试 代码质量分析)一般在5分钟内完成,单元测试中的外部依赖通过Mock的方式解决,这块我们会在后续的文章中专门讲解分析。持续集成保证了代码始终是可用的,编译正确并且通过所有单元测试和代码静态检测,这些动作都发生在代码部署到环境之前,是持续交付流水线的第一步。
2、自动化测试
互联网产品要求全回归测试要快,那么,如何在保证测试质量和测试覆盖率的前提下,有效锁定测试执行时间呢?首先,测试执行集群是很好的思路,通过并发机制提升执行效率,其次测试策略也是一个突破口。传统软件产品的测试策略,同时采用金字塔模型,这是迈克·科恩提出的,在很长一段时间内都被认为是测试策略设计的最佳实践。
但是,互联网产品具有快速迭代,微服务架构重后端等特性,我们应当遵循“重量级API测试,轻量级GUI测试,轻量级单元测试”的原则。以中间层的 API 测试为重点做全面的测试,尽可能提升自动化比率;轻量级的 GUI 测试,只覆盖最核心直接影响主营业务流程的;最上层的 GUI 测试通常利用探索式测试思维,以人工测试的方式发现尽可能多的潜在问题;单元测试采用“分而治之”,主攻稳定且核心业务。
虽然自动化测试的理念已经普及了好多年,但是据我了解很多企业内部,还是以手工测试为主,原因很多,比如人员缺乏和时间周期紧张,来不及写自动化测试脚本,或者测试人员的水平不足等。
我们在团队成立最初阶段,也同样存在此问题,测试人员是有开发自动化测试能力的,但是因为项目接连上线,时间周期紧张,测试人员忙于理解业务支持业务测试上线,没有独立的时间去完善自动化用例,彼时自动化测试相对薄弱。产品发布又需要不断迭代,每次发布都需要大量的测试人力投入,其中重复的测试工作占比不少,发布的次数越多,成本越高,限制了快速频繁发布的能力,我们曾一度裹挟在新业务功能测试和大量重复的手工回归任务中疲于应对,也有过为了节省时间成本,仅通过开发人员对于功能调整影响范围的预估,缩小回归测试的范围,承担了线上事故带来的苦果。
经过权衡,我们下决心要大力推动自动化测试,专门抽调人员成立自动化小组,虽然短期内对业务上线时间造成一定影响,但是我们顶着压力度过了困难期,陆续完成了API自动化测试平台,性能测试平台、Web-UI自动化框架、APP云测、Mock Server等系统,并和持续交付平台很好地结合到一起。API测试平台是我们自动化测试的核心,下图是平台架构,实现了测试数据和逻辑的分离,同步异步API结果验证,连续且参数传递API用例测试,微服务下API消费契约测试等主要功能,其中核心处理器既能手动触发也能提供rest的接口供持续交付流水线调用。具体的内部实现逻辑我在另外一篇API测试实践的文章中再细谈。
3、交付流水线
交付流水线包括了从开发提交代码,触发构建,部署测试环境,测试环境自动化以及测试、准生产环境部署到测试、上线审批、自动化发布上线及测试。下面是交付流水线的页面截图,每一个节点的状态通过颜色区分,还可以点击查看节点的具体发送和响应信息。纵观整个流水线,是自动化和人工相结合的一个过程,测试环节需要人工测试的参与,任何节点如果自动执行失败的话,也要提供人工介入的入口,允许人工选择重新执行、终止流程等动作,涉及上线需要人工审核才能触发自动化发布节点等等,所以,流水线也不是一味追求自动化,需要自动和人工的结合。
4、环境部署
在环境部署这一环节,目前通过Docker以“容器化“的方式部署应用。利用容器化的快速部署优势实现流水线快速推进;利用容器化高可扩展性的优势实现基于负载的自动伸缩;利用容器化更加轻量级的优势解决了应用和操作系统的强耦合问题;利于容器化高一致性的优势统一构建各环境,提高部署环境的一致性。在DB申请环节,DB也是基于容器化来实现的,统一各环境的数据库表结构,个性化各环境的独有数据,比如账户信息、商户信息等数据,并提供快速保存功能以增量的方式保存关键数据的更改。具体架构见下图。流水线上的几点各司其职,尤其镜像制作比较复杂,我们通过镜像管理平台实现镜像制作以及线下到线上的转推。应用交付方式和过程归一化,并通过平台实现自助化和自动化。
以上通过持续集成、自动化测试、流水线以及自动化部署几个要素对持续交付平台做了介绍。持续交付的价值应该体现在提升软件交付效率,统一企业的软件交付流程和规范,保证软件交付质量和降低软件发布风险等方面,因为每个公司内部结构、形式都不一样,一套方案肯定不能适用于所有公司,只有最适合自己公司的东西才是最好的方案,我们团队也在努力总结经验,摸索前行,不断完善符合自身特色的持续交付平台。
作者:孙鹰