部署流水线(deployment pipeline)是持续交付1.0的核心模式。它是对软件交付过程的一种可视化呈现方式,展现了从代码提交、构建、部署、测试到发布的整个过程,为团队提供状态可视化和即时反馈。部署流水线的设计受到软件架构、分支策略、团队结构以及产品形态的影响,因此每个产品的部署流水线均有所不同。
本章将重点介绍产品团队设计和使用部署流水线的基本原则,以及企业开发部署流水线平台工具链时,需要构建的平台能力要求,以及相关子系统的服务逻辑架构。
让我们先从一个简单的部署流水线案例开始吧!
7.1 简单的部署流水线(示例)
我们以2008年商业套装软件产品Cruise为例,来解释持续交付部署流水线的概念。该产品思想最早来源于开源软件CruiseControl的企业版本。Cruise自2008年第一个版本发布以后,每3个月发布一个商业化版本,供全球企业用户试用和购买。截至2010年,代码行数约为50000行,自动化单元测试和集成测试用例约为2350个,端到端功能测试用例约为140个。后来更名为「GoCD」,并将社区版开源后,放到了网站上。以下均以“GoCD”之名进行描述。
7.1.1 简单的产品研发流程
GoCD系统是典型的Server/Agent架构,服务器和客户端各自可独立启行。服务器本身曾是一个典型的巨石应用,包含关系型数据库和Java应用服务器。用户可以通过浏览器访问其Web服务,同时它也提供RESTful API接口,方便用户进行程序扩展,架构示意图如图所示:
服务器和代理的代码(包括自动化测试代码)全部保存于同一个代码仓库,版本控制软件使用的Mercural是(与Git类似的分布式版本管理工具),团队成员均有权修改代码库中的任何代码。产品研发团队的总人数保持在12人左右。在产品版本交付期中,迭代周期为一周。团队自身也使用该产品进行持续集成与持续交付实践。在每个迭代结束后,用最新版本替换团队自己正在使用的旧版本。每两个迭代将试用版本部署到公司内部的公用服务器上,供公司其他团队使用。若公司内部试用版本运行质量达标,一周后再将该版本交付给该产品的试用企业,进行外部企业用户早期体验,如图所示:
由于团队使用「测试驱动开发」方法,因此开发人员编写所有的自动化单元测试用例与功能自动化测试用例,并负责维护它们。单元测试的行覆盖率在75%~80%波动。
7.1.2 初始部署流水线
GoCD团队遵守「持续集成六步提交法」(参见第9章),任何人提交代码后,立即自动触发一次部署流水线实例化,该部署流水线如图所示:
第一个阶段是“提交构建”(自动触发,自动执行):包括7个并行自动化任务,分别是编译打包、代码规范静态扫描、5个不同的自动化单元/集成测试用例集合,使用自动触发机制。产品的自动化集成测试也使用单元测试框架编写,并在提交构建阶段与单元测试一起执行。由于GoCD支持多种操作系统,因此在这一阶段会同时构建生成对应不同操作系统的软件包,如deb文件、.exe文件、.zip文件等。这些安装文件生成以后,可供后续所有阶段使用。后续所有阶段不再重新编译打包。
第二个阶段是“次级构建”(自动触发,自动执行):包括两个并行自动化功能测试集任务,分别运行于两类环境,即Windows/IE和Linux/Firefox浏览器,并且两个环境中所用的测试用例集相同,使用自动触发机制。
第三个阶段开始,每个阶段都只有一个任务。
第三个阶段是“UAT部署”(手工触发):将软件包部署到手工UAT环境(用户验收环境,User Acceptance Environment)
第四个阶段是“UAT结果”(手工触发):测试人员“手工验证”完成后,将其标记为“验收通过”
第五个阶段是“性能测试”(手工触发):就是做自动化性能测试。
第六个阶段是“内部体验”:就是将Alpha版本部署到企业内部服务器,给内部其他团队试用。
第七个阶段是“外部体验”:就是将Beta版本发给外部的企业用户体验。
第八个阶段是“上传发布”:就是上传版本。将确定的商业发布版本上传到指定服务器,供用户登录产品网站自行下载。
每次提交代码后,部署流水线的「提交构建」都会被自动触发。「提交构建」成功后会自动触发「次级构建」。提交构建阶段的7个任务中,执行时间最长的是单元测试,其中JavaScriptFu和Java单元测试用例与集成测试用例共有2350个,被分成5个测试集,最长的一个测试集持续时间约为15分钟。「次级构建」的两个并行任务,端到端功能验收测试140多个,执行时间最长需要约30分钟。
第三个阶段(UAT部署)由测试工程师手工触发。测试工程师根据具体需求完成情况,在已经通过次级构建阶段的那些构建中,选择一个被测版本,向UAT环境部署软件包,用于手工验收测试。如果该版本通过了手工验收测试,则测试人员会手工触发第四个阶段,系统自动标记该版本为已测试通过版本。
第五个阶段的「性能测试」也是手工触发。
7.1.3 流水线执行状态解析
开发人员每次提交代码都会触发一次部署流水线。测试人员只从通过「次级构建」的那些版本中选择包含新功能的版本进行UAT部署,并进行手工测试。验收结束后,触发“UAT结果”。团队会定期触发性能测试。这个部署流水线的运行实例示意图:
团队开发工程师每人每天都会提交一次。因此,这个部署流水线每天都会启动多次。当然并不是每次提交的变更都会走到最后的「上传发布」。也不是每次提交都会走到「UAT部署」,因为开发人员并不是完成一个功能需求后才提交代码,而是只要做完一个开发任务,就可以提交。每个功能可能由多个开发任务组成,开发工程师需要确保即便提交了功能尚未开发完成的代码,也不会影响已开发完成的那些功能。
7.2 部署流水线的设计与使用
上面介绍的GoCD团队的部署流水线虽然是一个简单的部署流水线,但其设计及运作方式体现了团队使用部署流水线的设计原则与协作纪律。
7.2.1 流水线的设计原则
流水线的设计遵循以下原则:
当某个部署流水线的一次运行实例构建出制品(如二进制软件包),如果需要,它就应该直接被用于该流水线后续阶段的构建过程,而不是在后续阶段中被再次重复构建。如果该部署流水线实例触发了下游流水线,并且下游流水线也使用该制品,那么,部署流水线工具应该确保它来自上游部署流水线的同一个实例。只有这样,我们对该制品的质量信心才能随着部署流水线的前进而增加。例如,在图7-4中,构建号为521的部署流水线实例中,其内部发布阶段所用的软件包就是同一构建号521的提交构建阶段生产出来的二进制产物。
部署流水线工具应该与具体的部署构建业务相分离。我们不应该为了方便实现自动化,而将软件代码的构建和部署过程与所选择的部署流水线工具紧耦合。例如将一些软件部署时所用的脚本或所需信息由部署流水线平台保存。相反,我们应该提供单独的脚本,并将其放入该产品的代码仓库中。这样就可以轻松对这些脚本的修改进行跟踪和审核。也就是说,仅仅将部署流水线平台工具视为任务的调度者、执行者和记录者,它只需要知道部署流水线中各种任务触发与调度流程,而不必知道我们如何构建和部署软件。
在部署流水线的设计中,我们也应该尽可能考虑并行化。在GoCD的部署流水线中,很多阶段都有并行任务。例如,提交构建阶段中有5个自动化测试任务,它们各自包含不同的测试用例,在不同的计算节点上运行。简而言之,应该尽早提供质量反馈信息,从而及时修正发现的问题。

本文阐述了部署流水线的设计原则及其对企业持续交付流程的重要性。介绍了部署流水线的基本概念、关键组成部分,以及如何构建和使用部署流水线。此外,还探讨了部署流水线平台的构成与能力要求,基础支撑服务的云化管理,以及不同类型产品的部署流水线示例。
最低0.47元/天 解锁文章
1664

被折叠的 条评论
为什么被折叠?



