谈DevOps-持续交付01(11.28)

注:图片来源于网络

今天谈下DevOps成熟度模型里面的持续交付,由于这个过程域里面的内容比较多,因此准备分两次来谈,这次只谈
配置管理,构建和持续集成,测试管理,部署和发布管理

四个。

首先我们看下持续集成的定义,即持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。 每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

从这个定义里面可以看到重点在于集成两个字,即多个开发人员的代码每天要进行一次集成,如何检验集成成功?即我们说的执行了自动化的编译构建,并运行自动化的测试。

而在DevOps里面更加强调持续交付,这个和持续集成的区别就是 持续交付的整个生命周期过程更长了,面向的是最终客户,最终的生产环境 ,因此不是简单的集成成功就完事,更加重要的就是向客户,向生产环境的交付是成功的,是可以持续进行的。这是两者最大的区别。

我最近在细读DevOps成熟度模型,再次感觉整个内容粗看很完整,但是细看感觉就很乱,其体系化和严谨程度和CMMI,PMBOK等比较起来差距很大。出来的很仓促,而且很大的一个反映就是参与编写人员很多不是来自于一线DevOps项目实践。

我一直强调,很多体系和模型的建设,一定是需要大量多样性实践后才能够完成核心通用价值的抽象。

1. 配置管理

配置管理是对所有与项目相关的产物,以及它们之间的关系都被唯一定义,修改,存储和检索的过程,保证了软件版本交付生命周期过程中所有交付产物的完整性,一致性和可追溯性。 配置管理是持续交付的基础,是保障持续交付正确性的前提,良好设计的配置管理策略,可提高组织协作效率,改善产品价值交付流程。

配置管理分为了版本控制和变更管理两个子内容 ,实际上对于配置管理的内容,完全可以参考CMMI二级里面的配置管理过程域,内容相当来说更加细化和完整。

对于版本控制首先要谈的的就是不仅仅是源代码,而是整个软件交付过程中涉及到的源代码,配置文件,数据库脚本,工具环境,数据,产品相关文档等都应该纳入到版本控制系统中进行管理。所有的上述内容都应该对应到具体的版本,同时所有的变更都应该针对相应的版本进行,有变更也一定涉及到版本变化。

其次版本控制里面的一个重点就是我们常说的分支策略和集成策略,究竟应该定义几个分支?分支如何向主干合并,频率又如何,如何管理冲突都是应该考虑的问题。

在DevOps最佳实践里面可以看到,一定是不需要对开发,测试,生产,Bug等都构建出来不同的分支,太多的分支本身也会导致我们管理复杂度的增加。

那么在持续交付的过程中,分支如何建设是一种比较好的方案?

初步思考来说, 至少应该是建立开发和生产两个分支,生产版本稳定性不高则再增加Bug分支 ,即一个版本所有的测试都通过准备向生产交付的时候,开发环境分支代码打标签和基线,然后讲代码Deliver到生产分支。这个时候开发分支可以开始下一个迭代版本的开发和变更,仍然是进行持续集成。

这种方式可以解决我们实际中的如下几个问题

1. 生产环境被破坏需要重新部署但是镜像本身也丢失,那我们可以在生产分支重新构建并部署

2. 生产环境出现Bug需要修复,我们直接在生产分支修改Bug后进行持续集成,单独起一个Bug验证环境

3. 将Bug修改同时在生产分支和开发分支进行修改

可以看到,如果我们不希望做第3步,那么还需要启用Bug分支,然后朝开发和生产分支进行Deliver操作。具体是否启用Bug分支需要看本身生产环境版本的稳定程度。

以上是针对一个项目的情况,但是如何我们一个软件产品面向前方多个项目,每个项目都可能存在定制开发的时候如何处理?这个也是我们开发团队经常会遇到的很现实的问题。

那我们来看下 如何现在需要支撑A,B,C三个项目的软件定制化需求开发。实际上我们需要在主干分支上拉取三个独立的分支出来进行定制化开发 ,各项目定制的内容仅仅适用于各个项目本身。

1. 一个共性功能的添加? 需要在主干分支完成,然后Deliver到三个独立分支。

2. 一个Bug修改?如何A项目发现共性Bug,A-Bug分支修改,然后Devlier主干,再Deliver到B和C分支。

因此也可以看到,定制化的项目越多,我们实际上管理起来就越复杂。如何制定更好的分支管理策略是其一,更加重要的是如何划分好微服务模块,让共性模块尽量共性化提供公共能力,即对应基础共性模块不存在面对各个独立项目需要独立起分支情况,所有项目都用一个分支,一套代码来支撑。

变更管理是指软件系统中的所有变更都可以追溯变更的详细信息纪录,并向上追溯变更的原始需求,流转过程等所有关联信息。主要包括变更过程,变更追溯和变更回滚三方面 。可追溯性是版本回滚的历史依据和实施基础,建立良好的版本可追溯性可实现对任一版本完整环境流程的自动化,精确回滚,快速重现问题和恢复正常环境。

变更过程从变更请求发起开始,一直到变更影响分析,变更活动执行,变更验证关闭要形成闭环的流程,同时所有的变更都涉及到对配置项的修改,需要进行对应,才可能实现变更的全流程可追溯。

那我们再来看下变更的回滚,可以看到如果一个小版本有3个变更修改,如果都要回滚相对容易,我们可以直接退回到上一个基线版本,但是如果只回滚里面一个变更对代码文件的修改,相对来说就不容易,就还是需要人工去处理和识别具体需要回滚的内容。

2. 构建与持续集成

构建是将软件源代码通过构建工具转换为可执行程序的过程,一般包含编译和链接两个步骤,将高级代码语言转化为可执行的机器代码并进行相应的优化,提升运行效率。

构建实践是关注软件代码到可运行程序之间的过程,通过规则,资源和工具的有效结合,提升构建质量和构建速度,使构建成为一个轻量级,可靠可重复的过程。构建最终的产物采用清晰的版本进行标识,构建产物可以追溯,可回滚。

构建实践本身包括了构建方式,构建环境,构建计划和构建职责四个部分的内容。

对于构建实践本身最基本的要求就是通过构建脚本实现构建过程自动化,同时有专门的构建环境和服务器。在三级强调构建脚本复用和可管理性,构建环境配置的标准化; 在四级强调构建过程的可视化编排,构建资源的动态分配和回收,基于容器化的分布式集群的应用。

对于Java项目,我们一般会采用Jekins进行持续构建和集成。

Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行(这个比较抽象,暂且写上,不做解释)。Jenkins用、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle。

持续集成是软件工程领域中的一种最佳实践,即鼓励研发人员频繁的向主干分支提交代码,频率为至少每天一次。每次提交都触发完整的编译构建和自动化测试流程,缩短反馈周期,及时修复问题,从而保证软件代码质量,减少大规模代码合并的冲突和问题。 该过程主要包括了集成服务,集成频率,集成方式和反馈周期四个方面的内容。

对于持续集成,一方面是实现编译构建过程的自动化,一方面是实现测试过程的自动化,同时两者之间能够做到高效协同。 对于其它持续集成的内容,在上篇文章已经做了详细描述,再次不再展开。

3. 测试管理

测试管理是一个过程,通过该过程,所有和测试相关的方法,流程,人员都被定义。在产品投入到生产环境运行之前,通过测试过程验证产品的需求,尽可能地发现软件中的缺陷,从而提高软件产品的质量。 测试管理分为测试分层策略,代码质量管理和自动化测试三个维度进行表达。

注:图片来源网络

测试分层策略

对于测试分层管理在上篇文章做了简单说明

我们来谈下有哪些测试分类的方法,在持续集成里面我们当然更加会强调自动化测试,因此可以理解为人工测试和自动化测试两类;也可以离开为代码级测试,接口测试和前端测试分离。也可以理解为功能测试和非功能测试两类。

当然也可以看到,在微服务架构下,我们希望我们本身的开发也是分层的,即中台模块+服务接口+前台功能,即我们通常说的前后端分离,在这种前后端分离的情况下,可以更加方便我们进行测试分层设计和自动化测试。 只要是厚中台+薄前台模式,那么就越容易实现测试过程的自动化。

越是持续集成自动化承担越高,那么自动化测试的比重就会越大。

可以看到首先在架构设计上就要做到前后端分离,中台+服务+前台,这种分离后可以更加方便后面进行后端代码和接口的自动化测试工作。

可以看到在测试分层策略里面的四到五级描述里面,我们看到TDD测试驱动开发方面的内容,比如先写测试代码再写实现代码或者两者同时在进行等。其次,我们还是要将在整个devops最佳实践里面, 不仅仅开发过程是持续增量进行的,对于测试过程本身也是持续增量进行的,两者必须匹配。

或者理想状态应该是没有独立的测试周期,开发完成的阶段往往就是测试也配套完成的时间点。

代码质量管理

是软件研发过程中保证代码质量的一种机制,即在代码变更后,需要对代码进行检查,分析,并给出结论和改进建议,对代码质量数据进行管理,并可以对代码质量进行追溯。主要包括了质量规约,检查方式,反馈处理三方面的内容。

代码质量管理即我们常说的代码静态检查,其基于我们制定的代码质量规约进行。质量规约是指对软件代码质量的要求和规范,其中包含了编码规范,复杂度,覆盖率,以及安全漏洞,合规性要求等多个方面的内容。其中检查方式即包括了我们传统手工方面的检查和CodeReview,也包括了运行相关的自动化检查工具进行检查。

自动化测试

自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程,在预设条件下运行系统或应用程序,执行测试并评估测试结果,以达到节省资源和人力,提高测试效率和准确性,主要包括了自动化设计,自动化开发,自动化执行和自动化分析。

对于自动化测试可以看到,对于服务接口和代码级的自动化测试相对来说比较容易实现,但是对于前端和UI级的自动化测试相对来说就比较困难些。因此对于前期实践,我们也是建议先实现接口服务和代码级的自动化测试,再来靠前端UI的自动化测试。

对于性能测试由于可以提前录制脚本,相对来说自动化测试实现起来比较容易。不论是那种类型的自动化测试都可以看到,实际上可以看到如下几个关键点。

1. 自动化测试代码或脚本的编写,可以是人工编写,也可以通过录制生成。

2. 测试数据的产生问题,执行自动化测试前往往都涉及到测试数据的产生和使用,参考测试管理过程域

3. 自动化测试脚本能够重复执行的要求,这点必须要做到,确保每次持续集成都能够重复运行测试脚本

到了自动化测试的第四级开始,可以看到增加了对独立的自动化测试平台的要求,同时也增加了对测试结果分析和度量的要求,即通过测试结果的度量分析来进一步改进测试效率,提升代码质量。

Selenium高级自动化测试实战入门篇,参考:

https://ke.qq.com/course/126953?tuin=23746190&taid=583664580816873

4.部署和发布管理

部署和发布泛指软件生命周期中,将软件应用系统对用户可见,并提供服务的一系列活动,包括系统配置,发布,安装等。整个部署和发布过程复杂,往往涉及到多个团队之间的协同和交互,需要良好的计划和演练来保证部署发布过程的正确性。

部署偏技术实践,即软件代码,应用,配置和数据库变更到测试和生产环境的过程。而发布偏业务实践,是指将部署完成的应用软件功能正式对用户可见的过程,提供线上服务的过程。 即部署完了不一定就马上对业务和用户可见,而只有发布和配置完了才对用户可见,这样也就更好理解灰度发布的概念了。

部署和发布模式

部署和发布模式关注交付过程中的具体实践,将部署活动自动化并前移到开发阶段,通过频繁的演练和实践部署活动,成为研发日常工作的一部分,从减少最终部署的困难和不确定性,可靠可重复的完成部署发布任务。

最基本的要求是整个部署流程标准化和规范化,同时通过自动化的部署脚本进行部署操作。在三级就要求部署过程实现全自动化,同时应用和环境做为部署的最小单位,应用和配置进行分离。在四级要求部署过程灵活可编排可配置,可以一次自动部署多环境,可以支持灰度发布。

建立持续优化的部署监控机制,部署前能够进行自动化的测试,部署失败能够自动回滚。

部署流水线

部署流水线是DevOps的核心实践,通过可靠,可重复的流水线,打通端到端的价值交付,实现交付过程中各个环节活动的自动化和可视化。 部署流水线通过将复杂的软件交付流程细分为多个阶段,每个阶段层层递进,提升软件交付质量的信息,并且在流水线过程中提供快速反馈,减少后端环节浪费。

注意在三级里面流水线过程强调了打通软件交付过程中的各个环节,建立全流程的自动化能力,并根据自动化测试结果保证软件交付质量。在四级强调了可视化的部署流水线覆盖整个软件交付过程,每次变更都会触发完整的自动化部署流水线作业。

对于可视化的部署流水线,我仍然坚持我的观点, 即一定有一个顶层流水线是不仅仅是简单的到持续集成过程完成,而是覆盖到整个从sit到uat,从uat到生产的环境迁移过程 。简单来说,到生产的环境迁移本身就是一个持续交付的过程。

到生产的交付本身可以是独立的子流水线,因此我们在 流水线设计上面支持分层是相当重要的一个功能 。如果是两个独立的流水线,那么一定存在断点,但是完整的持续集成和交付过程一定是从需求和变更开始端到端驱动的,而不是随意可以触发执行的。