FYIRH 发表于 2021-12-25 19:12:16

持续交付的那些事儿

本帖最后由 FYIRH 于 2021-12-25 19:17 编辑


持续交付指的是在短周期内完成软件产品,以保证软件保持在随时可以发布的状态。让每一个变更都经过一条自动化的检验流水线,来检查每一个变更的质量,通过就进入下一个阶段。其不是一种工具,而是一种实践!
持续交付的共识和管理机制如下:

[*]不要阻塞开发人员,这是实现持续交付的本质理念
[*]为每个团队指定构建负责人或者发布工程师:优化交付流水线,提升交付效率
[*]项目状态应该对参与整个过程(包括构建、部署、测试和发布)的所有人都是可见的
[*]做好风险管理

[*]迭代增量式交付是有效风险管理的关键
[*]手工测试环境、试运行环境和生产环境总是需要严格的访问控制
[*]让风险识别成为每日立会的一部分


[*]做好审计

[*]手工测试环境、试运行环境和生产环境总是需要严格的访问控制:指定谁能够访问“特权”环境。
[*]要求每次部署都要进行审计,以确切知道到底修改了哪些内容。
[*]文档自动化、自文档

接下来先说明实现持续交付的一些基础设施和准备工作,然后从本地开发和自动化构建/部署流水线两方面说明持续交付的具体实现。
基础设施和准备工作
基础设施和环境管理让所有测试环境(包括持续集成环境)都要与生产环境相似:

[*]开发人员要把运维人员当做重要用户
[*]切忌吞噬错误信息
[*]使用运维团队熟悉的技术:开发人员最早负责创建部署脚本,后面移交给运维团队负责维护
[*]把创建和维护基础设施需要的所有内容都进行版本控制
[*]以自动化方式进行配置和部署!
[*]像对待生产环境一样对待测试环境!
[*]容器化技术实现不可变基础设施

配置管理版本控制、依赖管理、软件配置管理:

[*]各个环境的手工配置 -> 自动化配置
[*]对所有内容进行版本控制
[*]指定依赖库的确切版本,不要用快照或者模式匹配版本
[*]配置文件与二进制文件分离

测试策略

[*]创建全面的自动化测试套件:单元测试、组件测试、验收测试,每一种测试的代码覆盖率都高于80%以上
[*]每次修改都能运行一次自动化测试集合
[*]分层测试

数据管理

[*]把创建和迁移数据库全部变成自动化过程,是部署流程的一个组成部分
[*]让测试自己创建它们所需的状态,并确保每个测试都独立于其他测试
[*]对数据库进行版本管理,使用DbDeploy这样的工具管理数据迁移过程的自动化。
[*]在大多数据情况下,不要在测试中使用生产数据集的副本。?
[*]数据库回滚和无停机发布

[*]蓝绿部署
[*]大多数修改应该是增加操作(比如向数据库中增加新表或字段),尽可能不修改已存在的结构


[*]测试数据

[*]测试的独立性、原子性
[*]其他类型的测试,一定不要使用生产数据库的一个dump,除非有特殊情况


[*]部署流水线中的数据管理

[*]提交测试:快速运行,避免复杂的数据准备
[*]验收测试:后续阶段可以复用
[*]容量测试:为测试提供足够的输入数据,可以看做验收测试的重复利用


主干开发主干开发的分支模式实现持续交付最好的模式,但为了在主干模式下保持应用可发布,需要做到:

[*]每次创建分支,都要认识到它带来的成本
[*]频繁提交代码合并到主干
[*]新功能隐藏:功能开关统一管理达到特性隐藏的目的(Togglz?)
[*]增量开发:将所有的变更都变成一系列的增量式小修改,而且每次小的修改都是可发布的。
[*]抽象模拟分支(无法使用增量开发):修缮者模式,使用门面模式隔离待改造代码。
[*]使用组件,根据不同部分修改的频率对应用程序进行解耦。


本地开发
让开发者不受阻塞、不受不必要的干扰 -> 持续开发


[*]确保自动化测试、构建部署脚本都能够在开发机上运行
[*]本地自动化测试:预测试提交pretested commit/个人构建personal build/试飞构建preflight build【保证本地开发所有验证方式与流水线上的验证方式一致,提高开发人员在本地发现问题的能力】
[*]提交前在本地运行所有的提交测试,等提交测试通过后再继续工作
[*]在可控的环境上部署开发的应用程序
[*]修复破坏应用程序的任意修改是最高优先级的任务,构建失败后不要提交新代码

六步提交法
规范开发习惯。主动提前集成;小步提交、完整代码、不影响已有功能;关注代码规范、动静态扫描问题:

[*]检出最近成功的代码
[*]修改代码
[*]第一次个人构建
[*]第二次个人构建:拉取主干代码集成后本地测试
[*]提交代码到主干
[*]提交构

提交不影响已有功能!!

[*]增量迭代开发
[*]抽象模拟分支
[*]特性隐藏

规范化、自动化核心步骤

提高开发环境的效率:环境获取的服务化、自助化;环境的一体化、一致性:
1、本地开发环境

[*]共享机器池
[*]Git提交日志插入截图:Share Bucket+Google Drive
[*]远程开发机器/Web IDE
[*]依赖的服务

[*]维护一个单独的环境,让开发环境接入
[*]服务虚拟化工具来模拟依赖的服务,Mountbank、WireMock

2、联调环境:提供机器池,确保有两套空闲环境,自助化提供给开发者使用规范化、自动化本地检查:

[*]语法检查、规范检查、单元测试:Maven/Gradle插件

3、建设并自动化代码入库前的检查流程

[*]持续集成前的必要工作
[*]代码审查

代码审查
人工代码检查:

[*]统一并明确代码审查标准
[*]统一并明确日志提交规范
[*]传达团队的代码规则、质量基准
[*]LGTM(Looks good to me)

方式:

[*]代码入库前的设计时检查:在设计阶段进行代码审查

[*]代码入库前门禁检查,需要考虑灵活性,提供绕过机制
[*]代码入库后检查

[*]工具辅助的线下异步审查:依赖于Gitlab、Gerrit、Code Climate Engines,一对一审查
[*]面对面审查:架构问题、结对编程
[*]代码增量审查/代码全量审查
[*]团队审查:适合专项讨论
[*]代码审查计入工作量和绩效考评

代码提交规范:

[*]原子提交
[*]提交日志规范

原则:

[*]互相尊重
[*]基于讨论

快速反馈、增量开发
边开发边验证

[*]提高运行静态检查和测试的方便性、灵活性:Maven/Gradle插件
[*]提供沙盒环境方便验证和测试

[*]容器
[*]小范围的增量构建和验证?
[*]测试数据:直接使用生产环境、生产数据的导出并脱敏

[*]实时检验工具:IDE实时检验、Liveload

自动化构建/部署流水部署流水线就是对软件交付流程的建模。


实现部署流水线的一些共识如下:

[*]流水线建设原则

[*]测试尽量完整,保证产品质量->完备的测试机制
[*]运行速度够快->尽早反馈、提高交付速度
[*]使用的所有环境尽量和生产环境一致->复现问题

[*]所有相关角色提供构建状态可视化:持续交付流水线大屏显示
[*]存储构建结果报告
[*]只要有环节失败,就停止整个流水线!
[*]制品库是特殊的版本控制系统,不需要保存所有版本。
[*]为部署流水线的每个阶段创建脚本:脚本是系统中的一等公民
[*]增量式实现流水线:如果流程中有手工操作部分,就在流水线中为它创建一个占位符。

接下来从流水线的各个阶段分别说明。
提交阶段
从技术角度上断言整个系统是可以工作的。

[*]编译、单元测试、组装打包、代码分析
[*]少于五分钟,一定不要超过十分钟
[*]提交测试:单元测试、组件测试
[*]只有在某个错误让提交阶段的其他任务无法执行时,才停下来否则就直至提交阶段全部运行完后,汇总所有的错误和失败报告
[*]此阶段的结果:结果报告、二进制包、元数据

自动化验收测试验证一个用户故事或需求的验收条件是否被满足。针对业务!

[*]配置环境、部署二进制文件、冒烟测试、验收测试
[*]令验收测试失败的构建版本不能被部署
[*]先部署再测试,重用部署脚本。
[*]类生产环境运行验收测试:大部分是功能验收测试,关注功能正确性
[*]开发人员能够在自己的开发环境中运行自动化验收测试
[*]测试的关注点在系统的行为,而非数据本身。所以抵制使用生产数据的备份做为验收测试
[*]验收测试的性能不是主要考虑问题,重点在测试的全面性。
[*]正确地做验收测试:不要幼稚地对照着验收测试条件,盲目地把所有东西都自动化。
[*]验收测试可以看作所有后续测试阶段(包括容量测试)的某种模板:从部署准备开始,然后核实环境和应用程序都已被正确配置和部署,最后执行测试。

后续测试

[*]手工测试:探索性测试、易用性测试
[*]非功能测试:性能、安全、可维护、可扩展

部署发布
此阶段的触发不需要自动,测试或者运维人员可以做到自服务即可。

[*]对不同环境采用同一部署方式:使用同样的脚本向所有环境部署,包括开发机器
[*]一键式部署是对环境进行修改的唯一途径。
[*]部署测试:对部署进行冒烟测试,验证部署是否成功,证明其部署的可靠性
[*]确保部署流程是幂等的
[*]只有通过了自动化构建、测试和部署的那些修改才能发布!
[*]明确每个环境的部署和发布都是由谁负责
[*]发布计划:第一次发布,产出一些文档、自动化脚本或其他形式的流程步骤
[*]首次部署:首个迭代的主要目标之一就是在迭代结束时,让部署流水线的前几个阶段可以运行,实现部署流水线的“抽水泵”。

[*]部署流水线的提交阶段。
[*]一个用于部署的类生产环境。
[*]通过一个自动化过程获取在提交阶段中生成的二进制包,并将其部署到这个类生产环境中。
[*]一个简单的冒烟测试,用于验证本次部署是正确的,并且应用程序正在运行。

[*]对发布过程进行建模并让构建晋级

[*]为了达到发布质量,一个构建版本要通过哪些测试阶段
[*]每个阶段需要设置什么样的晋级门槛或需要什么样的签字许可。
[*]对于每个晋级门槛来说,谁有权批准让某个构建通过该阶段。

[*]将每次已通过验收测试的变更版本部署在试运行环境中
[*]紧急修复:紧急修复版本也要走完标准的部署流水线,与其他代码变更没什么区别。

[*]结对做!
[*]有时候回滚比部署新的修复版本更划算。

[*]持续部署:每当有版本通过自动化测试之后,就将其部署到生产环境中。【需要依赖强大的自动化测试机制】

度量
每次提交后都产生关于这些度量的报告和可视化效果并保存起来。

[*]周期时间(cycle time),从决定要做某个特性开始,直到把这个特性交付给用户的这段时间
[*]自动化测试覆盖率
[*]代码库特征
[*]缺陷数量
[*]交付速度
[*]提交版本库次数
[*]构建次数
[*]构建失败次数
[*]构建所花时间

其他
DevOps
DevOps是这些年很流行的一个概念,其目的就是打通研发和运维环节,以达到全员目标一致,保障软件高效交付。


[*]职能团队提供平台和工具,让全栈工程师能够自己处理端到端的工作,实现DevOps。
[*]全栈开发:工程师不再只是对某一个单一职能负责,而是对最终产品负责。

信息溯源
打通研发流程中流动的多种标识信息,以方便相关人员快速获取需要的信息,提高工作效率。包括任务工单、代码提交号、版本号、代码审查ID、测试用例ID、Bug ID。

[*]制品与源代码版本管理:放置在制品包中的元数据,体现源代码版本号。
[*]源代码与需求/Bug的版本关联:提交代码时需要在注释里注明需求ID、测试用例ID等。(转自飒然Hang)




页: [1]
查看完整版本: 持续交付的那些事儿