本节课程为《持续交付方法与实践》,将围绕三个方面展开, 为什么要做持续交付、如何做到高效的持续交付以及持续部署。

为什么要做持续交付

01 软件交付流程

想要理解为什么要做持续交付,就要先了解软件交付流程。

传统软件交付流程通常包括四个步骤:

→ 首先业务人员会诞生一个软件的想法;

→ 然后开发人员将这个想法变为一个产品或者功能;

→ 经过测试人员的测试之后提交给用户使用并产生收益;

→ 最后运维人员参与产品或功能的后期运维。

02 传统软件交付的问题和困境

通过分析以上流程,可以发现一些传统软件交付流程存在的问题。

①业务人员产生的需求文档沟通效率较低,有时会产生需求文档描述不明确、需求文档变更频繁等问题。

②随着开发进度的推进,测试人员的工作量会逐步增加,测试工作的比重会越来越大。而且由于测试方法和测试工具有限,自动化测试程度低,无法很好地把控软件质量。

③真实项目中运维的排期经常会被挤占,又因为手工运维繁琐复杂,时间和技术上的双重压迫会导致运维质量难以保证。

因为存在以上问题,所以传统的软件交付经常会出现开发团队花费大量成本开发出的功能或产品并不能满足客户需求这一双输的局面。由此可以总结出传统的软件交付存在两个层面的困境:

从表现层来看,传统软件交付存在进度不可控;流程不可靠;环境不稳定;协作不顺畅等困境。

表现层的问题其实都是由底层问题引起的,从根源上来说,存在分支冗余导致合并困难;缺陷过多导致阻塞测试;开发环境、测试环境、部署环境不统一导致的未知错误;代码提交版本混乱无法回溯;等待上线周期过长;项目部署操作复杂经常失败;上线之后出现问题需要紧急回滚;架构设计不合理导致发生错误之后无法准确定位等困境。

03持续交付的流程与优势

经过对传统软件交付问题的分析和总结,持续交付应运而生,持续交付是一系列开发实践方法,用来确保让代码能够快速、安全的部署到生产环境中。持续交付是一个完全自动化的过程,当业务开发完成的时候,可以做到一键部署。持续交付提供了一套更为完善的解决传统软件开发流程的方案。

①在需求阶段,抛弃了传统的需求文档的方式,使用便于开发人员理解的用户故事。

②在开发测试阶段,做到持续集成,让测试人员尽早进入项目开始测试。

③在运维阶段,打通开发和运维之间的通路,保持开发环境和运维环境的统一。

持续交付具备以下几个优势:

①持续交付能够有效缩短提交代码到正式部署上线的时间,降低部署风险。

②持续交付能够自动的、快速的提供反馈,及时发现和修复缺陷。

③持续交付让软件在整个生命周期内都处于可部署的状态。

④持续交付能够简化部署步骤,使软件版本更加清晰。

⑤持续交付能够让交付过程成为一种可靠的、可预期的、可视化的过程。

04 敏捷开发与Devops

持续交付依靠敏捷开发(Agile)和Devops两个组件的支撑可以更好地发挥作用。

敏捷开发(Agile)主要作用于需求阶段和研发阶段。

Devops主要作用于开发测试和运维部署阶段。

在这里我们主要讲解一下Devops的相关知识。

(1)Devops的趋势

根据最近的一项集体研究,DevOps的市场在2020年创造了约50亿美元的产值,预计到2022年,这个数字将达到约66亿美元。随着Devops的影响力不断扩大,目前DevOps已经成为软件工程的主流模式。

(2)Devops效能

Devops的效能跟发布频率、部署时间、平均修复故障的时间点、部署变更的失败率四个因素紧密相关。通常在高效的团队内,发布频率会达到每天多次发布、部署时间和平均修复故障时间都小于一小时,部署变更的失败率也能维持在15%以下。

05 软件交付能力指标

在评价互联网公司的软件交付能力的时候,通常会使用两个指标:

①仅涉及一行代码的改动需要花费多少时间才能部署上线,这也是 核心指标

②开发团队是否在以一种可重复、可靠的方式在执行软件交付。

目前,国外的主流互联网企业部署周期都以分钟为单位, Amazon、Google这些头部互联网企业单日的部署频率都在20000次以上。国内以百度、阿里、腾讯三大互联网巨头的数据来看,单日部署的频率也达到了单日8000次以上。高频率的部署代表着能够更快更好的响应客户的需求。

如何做到高效的持续交付

01 持续交付方法

为了能更好的做到高效的持续交付。在此我们提供了一个三层叠加的持续交付方法。

首先最上层,持续交付的总目标是价值交付,要为用户交付有价值的内容。

然后第二层包含了业务、流程、组织三个维度。

在业务这一维度,主要通过精益、用户故事地图、看板三种方式来减少业务部门与开发部门的沟通困难。

在流程这一维度,主要集中于创建一个供开发、测试、运维人员使用的可靠、可重复的流水线,将这种流水线应用于项目的流程中。

在组织这一维度,要求加强团队协作,提高项目质量和项目改进能力,并且引入了成熟度模型用于评估团队的能力层级。

如果没有技术能力的支撑,仅依靠方法和指导思想不足以做到高效持续交付。所以第三层也是最重要的底层是技术层。技术层包括了基础架构和应用架构。基础架构引入了容器集群管理、研发工具平台、持续交付工具链。应用框架引入了浮现式设计、微服务框架还有能够抽离出来的配置化架构。

02 持续交付、持续集成、持续部署的关系

要进一步构建可靠可重复的流水线,首先就是要理清持续交付、持续集成和持续部署三者之间的关系。

简单来说持续集成和持续部署是持续交付的基础,持续交付包括但不限于持续集成和持续部署。

持续集成是包含了代码的编译、近代检查、单元测试任务的集成,虽然持续集成也能构成一条流水线,但是这条流水线并不完整,而且集成并没有明确的目标。

近几年得益于虚拟机技术和容器技术的迅速发展,持续部署也逐渐变得简单高效,能够运用这些工具快速将项目部署到例如准入环境、预生产环境等等各种环境中。

03 如何构建一个可靠可重复的流水线

在理清持续交付的关系后,需要通过持续交付来构建一条可靠可重复的流水线,构建这条流水线的目的是为了让开发人员、测试人员、运维人员能更好的协作完成整个项目并上线到生产环境。

通过对比传统流水线和持续交付流水线,能更加清晰地展现出持续交付流水线的强大。

在传统流水线中,首先代码提交要用过填写表单的形式进行版本申请,然后开发人员在离线环境上手工进行代码编译和单元测试,单元测试完成后需要撰写对应的测试报告文档并且向上提测,在系统测试环节需要测试人员手动构建和部署测试环境,完成测试之后再次撰写测试报告,并且申请上线,在通过上线审批之后,在线上生产环境需要再次手动构建环境以及进行生产环境的测试,最终完成整体的开发。

在持续交付流水线中,代码合入到主干之后会直接触发自动编译,自动编译完成之后会进行初步的自动化单元测试、模块测试和系统测试,在测试过程中持续交付可以自动构建和部署环境。完成系统测试之后会将问题抛出来,解决完成后再次提测,会自动化的再次进行系统测试,通过系统测试之后可以一键操作进行项目发布,并进行预上线,在完成预上线后,可以再次进行一键操作完成正式生产环境的上线。

通过两种流水线的对比,可以看出来,持续交付的流水线有显著的优势。

实际生产中的产品级流水线,可以视为多个模块级流水线的组合,多个模块级流水线组合成为复杂的多线并发的产品级流水线,最终可以完成整个项目的持续交付。

04 交付流水线落地工具

交付流水线的落地需要依靠落地方案和落地工具,目前常用的落地方案有GoCD,这是thoughtworks的一个产品。还有目前广泛应用的Jenkins和Spinnakeer。

常用的交付流水线落地工具有效率云平台中的iPipe工具,在这个工具中可以根据需求创建流水线,并且将相关内容全都关联到流水线中,这样可以让开发人员、测试人员和运维人员在这个工具中直观的看到产品的状态以及质量情况。

持续部署

对于持续交付整体来说,持续部署非常重要。

01 持续部署方案

容器技术目前是部署中最流行的技术,常用的持续部署方案有Kubernetes+Docker和Matrix系统两种。容器技术一经推出就被广泛的接受和应用,主要原因是对比传统的虚拟机技术有以下几个优点:

①容器技术上手简单,轻量级架构,体积很小。

②容器技术的集合性更好,能更容易对环境和软件进行打包复制和发布。

容器技术的引入为软件的部署带来了前所未有的改进,不但解决了复制和部署麻烦的问题,还能更精准的将环境中的各种依赖进行完整的打包。

02 部署原则

在持续部署管理的时候,需要遵循一定的原则,内容包括以下几点:

①部署包全部来自统一的存储库。

②所有的环境使用相同的部署方式。

③所有的环境使用相同的部署脚本。

④部署流程编排阶梯式晋级,即在部署过程中需要设置多个检查点,一旦发生问题可以有序的进行回滚操作。

⑤整体部署由运维人员执行。

⑥仅通过流水线改变生产环境,防止配置漂移。

⑦不可变服务器。

⑧部署方式采用蓝绿部署或金丝雀部署。

03 部署层次

部署层次的设置对于部署管理来说也是非常重要的。首先要明确部署的目的并不是部署一个可工作的软件,而是部署一套可正常运行的环境。

完整的镜像部署包括三个环节:Build – Ship – Run。

Build跟传统的编译类似,将软件编译形成RPM包或者Jar包。

Ship则是将所需的第三方依赖和第三方插件安装到环境中。

Run就是在不同的地方启动整套环境。

制作完成部署包之后,每次需要变更软件或者第三方依赖、插件升级的时候,不需要重新打包,直接更新部署包即可。

04 不可变服务器

在部署原则中提到的不可变服务器原则对于部署管理来说非常重要。不可变服务器是技术逐步演化的结果。

在早期阶段,软件的部署是在物理机上进行的,每一台服务器的网络、存储、软件环境都是不同的,物理机的不稳定让环境重构变得异常困难。

后来逐渐发展为虚拟机部署,在虚拟机上借助流程化的部署能较好的构建软件环境,但是第三方依赖库的重构不稳定为整体部署带来了困难。

现阶段使用容器部署不但继承和优化了虚拟机部署的优点,而且很好的�