持续交付技术1:持续交付基本理念

文摘   2024-07-18 22:11   广东  

DevOps是当前还是很火热的概念,实践DevOps的方法涉及两个方面,一是如何持续管理需求、变更和及时处理用户反馈,通过工具固化一定的流程,有效的管理需求和变更。另一方面就是如何持续交付。

作为DevOps流程的核心实践持续交付(Continuous Delivery)在这其中能够为软件项目带来什么价值呢?本文将结合持续交付的具体实践展开分析与讨论。

1、什么是持续交付

2、持续交付的四大关键要素

3、推动软件持续交付的12个关键能力点

一、什么是持续交付?


首先来了解下持续交付的概念,在维基百科中持续交付的定义如下:

持续交付(Continuous delivery,缩写为 CD),是一种软件工程方法,让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定、持续的保持在随时可以发布的状况。它的目标在于让软件的编译、测试与发布变得更快更频繁。这种方式可以减少软件开发的成本与时间,减少风险。

好吧,看定义总是很抽象的,我们从两个维度来理解持续交付,一个是范围,一个是宗旨。

先说说范围,在信通院标准定义中,持续交付是指以可持续的方式将各类变更(包括新功能、缺陷修复、配置变化、实验等)安全、快速、高质量地落实到生产环境或用户手中的能力。
持续交付的分级技术要求包括:配置管理、构建与持续集成、测试管理、部署与发布管理、环境管理、数据管理、度量与反馈等,如图所示。

再看看持续交付的宗旨,持续交付的核心宗旨是:保证每次提交代码都产生一个可发布的版本。下图是持续交付的一个核心流程图,代码提交触发构建和单元测试,完成后触发自动化测试,根据自动化测试的结果进行审批是否进行用户验收测试,用户验收测试通过后进行发布上线。中间每一个环节都会产生反馈,一旦失败就终止当前交付流程。

工厂里的装配线以快速、自动化、可重复的方式从原材料生产出消费品。同样,软件交付管道以快速、自动化和可重复的方式从源代码生成发布版本。如何完成这项工作的总体设计称为“持续交付”(CD)。启动装配线的过程称为“持续集成”(CI)。确保质量的过程称为“持续测试”,将最终产品提供给用户的过程称为“持续部署”。

“持续”是什么意思?

“持续”用于描述遵循我在此提到的许多不同流程实践。这并不意味着“一直在运行”,而是“随时可运行”。在软件开发领域,它还包括几个核心概念/最佳实践。这些是:

1.频繁发布: 持续实践背后的目标是能够频繁地交付高质量的软件。此处的交付频率是可变的,可由开发团队或公司定义。对于某些产品,一季度、一个月、一周或一天交付一次可能已经足够频繁了。对于另一些来说,一天可能需要多次交付也是可行的。所谓持续也有“偶尔、按需”的方面。最终目标是相同的:在可重复、可靠的过程中为最终用户提供高质量的软件更新。通常,这可以通过很少甚至无需用户的交互或掌握的知识来完成(想想设备更新)。
2.自动化流程: 实现此频率的关键是用自动化流程来处理软件生产中的方方面面。这包括构建、测试、分析、版本控制,以及在某些情况下的部署。
3.可重复: 如果我们使用的自动化流程在给定相同输入的情况下始终具有相同的行为,则这个过程应该是可重复的。也就是说,如果我们把某个历史版本的代码作为输入,我们应该得到对应相同的可交付产出。这也假设我们有相同版本的外部依赖项(即我们不创建该版本代码使用的其它交付物)。理想情况下,这也意味着可以对管道中的流程进行版本控制和重建(请参阅稍后的 DevOps 讨论)。
4.快速迭代: “快速”在这里是个相对术语,但无论软件更新/发布的频率如何,预期的持续过程都会以高效的方式将源代码转换为交付物。自动化负责大部分工作,但自动化处理的过程可能仍然很慢。例如,对于每天需要多次发布候选版更新的产品来说,一轮集成测试(integrated testing)下来耗时就要大半天可能就太慢了。

    通过这范围和宗旨两方面,和持续的核心概念,是否已经有些了解持续交付是什么了呢?如果还是不了解,不急,接下来我们针对持续交付的整个流程进行拆分。

从代码提交开始,我们可以把整个持续交付归纳出四个关键要素:持续集成、自动化测试、交付流水线,自动化部署。

二、持续交付四要素


从代码提交开始,我们可以把整个持续交付归纳出四个关键要素:持续集成、自动化测试、自动化部署、交付流水线。下面分别从四个关键要素解读我们的持续交付平台。

1、持续集成

将代码开发和集成按模块拆分成多个小阶段,每一阶段完成后都会进行集成,这在一定程度上减少了风险。我们要求在代码提交时即触发编译。构建时会对整个应用的所有模块进行编译,并伴随单元测试以及代码质量分析。如果构建过程失败了,那么必须立即邮件告警到相关开发责任人,并责令立即修复问题,如果20分钟内无法修复,就要回退代码提交,总之,要求代码库的代码持续处于可用状态。目前,每次成功的构建(编译+单元测试+代码质量分析)一般在5分钟内完成,单元测试中的外部依赖通过Mock的方式解决,这块我们会在后续的文章中专门讲解分析。持续集成保证了代码始终是可用的,编译正确并且通过所有单元测试和代码静态检测,这些动作都发生在代码部署到环境之前,是持续交付流水线的第一步

2、自动化测试

互联网产品要求全回归测试要快,那么,如何在保证测试质量和测试覆盖率的前提下,有效锁定测试执行时间呢?首先,测试执行集群是很好的思路,通过并发机制提升执行效率,其次测试策略也是一个突破口。传统软件产品的测试策略,同时采用金字塔模型,这是迈克·科恩提出的,在很长一段时间内都被认为是测试策略设计的最佳实践。

但是,互联网产品具有快速迭代,微服务架构重后端等特性,我们应当遵循“重量级API测试,轻量级GUI测试,轻量级单元测试”的原则。以中间层的 API 测试为重点做全面的测试,尽可能提升自动化比率;轻量级的 GUI 测试,只覆盖最核心直接影响主营业务流程的;最上层的 GUI 测试通常利用探索式测试思维,以人工测试的方式发现尽可能多的潜在问题;单元测试采用“分而治之”,主攻稳定且核心业务。

什么是“持续测试”?

持续测试是指在代码通过持续交付管道时运行扩展范围的自动化测试的实践。单元测试通常与构建过程集成,作为持续集成阶段的一部分,并专注于和其它与之交互的代码隔离的测试。除此之外,可以有或者应该有各种形式的测试。这些可包括:
1.集成测试: 验证组件和服务组合在一起是否正常。
2.功能测试: 验证产品中执行功能的结果是否符合预期。
3.验收测试: 根据可接受的标准验证产品的某些特征。如性能、可伸缩性、抗压能力和容量。

所有这些可能不存在于自动化的管道中,并且一些不同类型的测试分类界限也不是很清晰。但是,在交付管道中持续测试的目标始终是相同的:通过持续的测试级别证明代码的质量可以在正在进行的发布中使用。在持续集成快速的原则基础上,第二个目标是快速发现问题并提醒开发团队。这通常被称为快速失败。

3、交付流水线

持续交付是一个大流程,从代码提交一直到部署上线,但是我们在实践过程中发现,这种大流程,未免太大太笨重。在企业真实的情况下,大流程本身没问题,但是其中的环节往往没有这么简单,想要让这个流水线真正能被企业实际使用,还要对大流程进行拆分。我们在实践中把持续交付流水线拆分成三个子流水线:开发流水线、集测流水线、发布流水线

开发流水线:

面向开发人员和开发环境。开发人员提交代码,触发构建,部署到开发环境中由开发人员进行自测。这个流水线在开发的过程中会频繁进行。

集测流水线:

面向测试人员,同样以构建为开始,基于构建的产物(部署介质),部署到集成测试环境,进行系统集成测试。

发布流水线:

当次发布的所有需求全部通过系统集成测试后,便可以进入后续测试如用户验收测试、非功能性测试等,通过后,则认为已经达到发布上线标准,触发上线申请审批流程,审批通过可以进行自动化发布上线。

在项目中,开发流水线的触发频率最高,集测流水线其次,发布流水线触发的频率最低。

将整个的持续交付流水线拆分为三个子流水线,可以做到面向不同的角色,这样更灵活也更便于使用。当然,不同企业的流程也是有着区别的,不一定严格按照这三个流水线。即使定义成这三个流水线,每个流水线的流程和环节也是不同的,可以结合自己企业的实际流程来拆分。


4、自动化部署

在自动化部署这一环节,目前通过Docker以“容器化“的方式部署应用。利用容器化的快速部署优势实现流水线快速推进;利用容器化高可扩展性的优势实现基于负载的自动伸缩;利用容器化更加轻量级的优势解决了应用和操作系统的强耦合问题;利于容器化高一致性的优势统一构建各环境,提高部署环境的一致性。在DB申请环节,DB也是基于容器化来实现的,统一各环境的数据库表结构,个性化各环境的独有数据,比如账户信息、商户信息等数据,并提供快速保存功能以增量的方式保存关键数据的更改。具体架构见下图。流水线上的几点各司其职,尤其镜像制作比较复杂,我们通过镜像管理平台实现镜像制作以及线下到线上的转推。应用交付方式和过程归一化,并通过平台实现自助化和自动化。

以上通过持续集成、自动化测试、流水线以及自动化部署几个要素对持续交付平台做了介绍。持续交付的价值应该体现在提升软件交付效率,统一企业的软件交付流程和规范,保证软件交付质量和降低软件发布风险等方面,因为每个公司内部结构、形式都不一样,一套方案肯定不能适用于所有公司,只有最适合自己公司的东西才是最好的方案,我们团队也在努力总结经验,摸索前行,不断完善符合自身特色的持续交付平台。

三、推动软件持续交付的12个关键能力点


(一)持续交付能力

1.对所有生产工件使用版本控制

版本控制是将所有生产工件纳入版本控制系统(例如GitHub或Subversion)管理,包括应用程序代码,应用程序配置,系统配置以及用于自动构建和配置环境的脚本。

2.使用基于主干开发方法

基于主干的开发模式已被证明可以实现软件开发和交付中的高性能。它的特点是在代码存储库中少于三个活动分支。在合并入主干分支之前具有非常短的生命周期(例如,少于一天)的分支;应用程序团队很少或从来没有“code lock”期,因为合并冲突,代码冻结或稳定阶段,没人能签入代码或执行拉取请求。

3.实施持续集成和测试自动化

持续集成(CI)是实现持续交付的第一步。这是一种开发实践,其中的代码会定期检入,每次检入都会触发一组快速测试,以发现严重的回归问题,开发人员会立即对其进行修复。CI流程将创建规范的构建和程序包,并最终进行部署和发布。

测试自动化是一种在整个开发过程中自动(而非手动)连续运行软件测试的实践。有效的测试套件是可靠的,也就是说,测试会发现真正的失败,并且只能通过可发布的代码。请注意,开发人员应主要负责创建和维护自动化测试套件。

4.实施持续交付(CD)和部署自动化

部署自动化是指部署完全自动化且不需要人工干预的程度。

CD是一种开发实践,其中软件在其整个生命周期中都处于可部署状态,并且团队优先考虑使软件保持在可部署状态,而不是研究新功能。所有团队成员都可以快速获得有关系统质量和可部署性的反馈,当他们收到有关系统不可部署的报告时,可以快速进行修复。最后,可以根据需要随时将系统部署到生产或最终用户。

(二)架构能力

5.使用松耦合的架构

这影响了团队可以按需测试和部署其应用程序的程度,而无需与其他服务进行协调。松散耦合的架构使您的团队能够独立工作,而无需依赖其他团队的支持和服务,从而使他们能够快速工作并为组织创造价值。

6.跨应用程序和基础架构进行监视以通知业务决策

使用来自应用程序和基础架构监视工具的数据来采取行动并制定业务决策。当出现问题时,这不仅仅可以传呼别人。

(三)组织与管理能力

7.通过价值流使工作流程可见,并收集并实施客户反馈

团队应该对从业务一直到客户的工作流程有很好的理解和可视性,包括产品和功能的状态。我们的研究发现,这对IT性能有积极影响。

我们的研究发现,组织是否定期主动地寻求客户反馈,并将此反馈纳入其产品设计对软件交付性能很重要。

8.小批量工作

团队应该将工作分成小块,可以在一周或更短的时间内完成。关键是将工作分解为允许快速开发的小功能,而不是在分支上开发复杂的功能并很少发布它们。这个想法可以应用于功能和产品级别。(MVP是产品的原型,具有足够的功能以使人们能够有效地了解产品及其商业模型。)小批量工作可缩短交货时间并加快反馈循环。

9.改进流程并管理在制品(WIP)限制的工作

在精益社区中,使用在制品限制来管理工作流程是众所周知的。有效使用后,可提高流程效率,提高吞吐量并在系统中显示约束。

10.可视化工作以监视质量并在整个团队中进行沟通

已显示用于监视质量和在制品的视觉显示,例如仪表板或内部网站,有助于软件交付性能。

11.鼓励和支持学习,支持和促进团队之间的合作

这反映了传统上孤立的团队在开发,运营和信息安全方面的互动程度。

在您的文化中,学习被认为对持续进步至关重要吗?学习被视为成本还是投资?这是对组织学习文化的一种衡量。

12. 支持或体现变革型领导

变革型领导支持并扩大了DevOps中至关重要的技术和流程工作。它由五个因素组成:视觉,智力刺激,鼓舞性沟通,支持性领导和个人认可。



研发效能方法论
分享内容的四大方向:研发效能和软件工程方法论,软件工程技术,平台工程设计,通用五力