软件工程:持续交付,如何做到随时发布新版本到生产环境

持续交付已经成为一种公认的好的开发实践,越来越多的开发团队都已经应用持续交付,它通过自动化的方式,让你的代码在每一次提交后,都能自动化的走完编译,测试流程,完成后就可以随时准备好部署发布。

持续交付如果细分,其实可以分为持续集成、持续交付和持续部署三个概念,这三个概念很相近,但又有所不同。

集成、部署和交付的发展史

要想更好的理解和应用好持续集成、持续交付和持续部署,必须先了解它们的演变史。持续集成、持续交付和持续部署的历史还不算太长,但是集成、部署和交付却是伴随着软件工程一起发展的。

集成的发展演变

在多人软件项目开发的时候,每个人都会负责一部分功能模块的开发,集成指的就是每个人把自己开发的分支代码,合并到主干上,以便测试打包。

集成的原始阶段

早在瀑布开发的年代,在开发阶段,一般是不集成的。大家各自开发,等到开发阶段差不多快结束了,再一起提交代码到源代码管理工具,让代码集成在一起,再编译、部署发布到测试环境。

由于长时间都是在各自的开发环境中运行,每次集成都是很痛苦的过程,会遇到各种问题,比如说编译无法通过、hard code了开发环境地址、类库版本不一致、API格式不一致等。通常要持续几天甚至几周才能逐步有一个相对文档的版本

在这里插入图片描述

从手动集成到自动化的持续集成

《重构》的作者 Martin Fowler 说过:“如果一件事很痛苦,那么就更频繁的做”。持续集成本质上也是把集成这件让人痛苦的事情,更加频繁的做。
在这里插入图片描述
瀑布模型开发的集成,或者说传统的集成,都是在开发阶段整体完成的差不多了,才开始集成。而持续集成的做法,则是每次有代码合并入主干之前,都进行集成,持续的集成。代码集成到主干之前,必须通过自动化测试,只要有一个测试用例失败,就不能集成

持续集成的好处很明显:

  • 配合自动化测试,这样可以保障主干的代码是稳定的
  • 频繁集成可以让开发人员总能从主干及时获得最新的代码,不至于像类库、API不一致等问题到最后测试的阶段才暴露出来

持续集成主要的问题就是搭建整个持续集成环境,要稍微麻烦一点,另外需要配合一些流程规范来辅助执行,比如要求有一定的自动化测试代码的覆盖率,要求测试通过才能合并到主干

部署和交付的发展史

部署指的是代码发布到各种环境,比如部署测试环境以供测试。交付指的是软件产品在测试验收通过后,句柄发布到生产环境交付给客户使用的条件。

部署和交付的原始阶段

在早些年,部署是一件很麻烦的事情,需要手动获取最新源代码、编译,再需要针对环境修改很多配置。

生产环境就更麻烦了,因为出错了会导致服务中断。最初部署的生成环境是开发人员自己做的,根据自己的经验把程序部署,然后手动修改很多配置,以保证正常运行。但这样经常会遗落一些配置,导致程序无法正常运行,出问题后程序员很肯能会直接在线上环境修复bug,导致更大问题。

随着分工的进一步细化,逐步发展成有专门的运维岗位,由运维人员负责部署。而开发人员上线前要写专门的部署文档和检查表,运维人员按照部署文档和检查表一步步部署生产环境。

这样确实有效减少了配置错误等问题,但是整个部署过程还是很繁琐,尤其是服务器一多,耗时很长,仍然可能因为人工操作错误导致失败。

所以为了部署出问题,会尽量避免进行生成环境部署,几周甚至几个月才部署一次

从手动部署到脚本自动化部署

对于程序员来说,如果一件事能自动化解决,迟早会有人找出自动化的解决方案,部署也由原来的手动部署发展成为自动化部署。

早期的自动化部署解决方案是每日构建(Daily Build),简单来说,就是大家在每天晚上下班后,每日构建程序自动从源代码管理器下载最新代码,编译、部署程序到测试环境。这样第二天测试人员就可以拿到最新的程序,对前一天修复的bug进行测试。

每日构建是个很大的进步,因为初步实现了自动化对代码进行编译、部署测试环境。但也有一些不完善的地方,比如说如果有开发人员提交的代码有问题,可能会导致当天的编译或者部署失败,那么第二天开发人员上班后,还需要手动解决。

你会发现,自动化逐步应用到运维领域,确实是让部署过程更容易,但也只是让部署过程更容易,还是无法解决发布版本的质量问题,还是可能会因为配置错误导致失败,测试环境正常的功能到生产环境就不工作了。

从脚本部署到持续交付

其实在理解了持续集成后,在理解持续交付就容易多了。持续交付,就是在持续集成的基础上,再进一步,在功能合并到主干后,不仅会自动化测试,还会打包,并部署到测试环境中。

理论上来说也可以直接部署到生产环境,但是这个环节需要人工确认。参考下图,红色部分表示需要手动确认。

在这里插入图片描述
持续交付本质上也是把部署和交付这件让人痛苦的事情,更加频繁地去做,从而让部署和发布变得不但不痛苦,反而越来越简单。

把持续交付的工作做好后,部署生产环境会变得非常简单,只需要点一下按钮或者运行一个命令,就可以很快完成,不需要人为的去修改配置等手动操作,也将因为配置错误或者环境不一致导致的问题的可能性降到了最低。

从持续交付到持续部署

持续交付,对于生产环境的部署,依然需要有手动确认的环节。而持续部署,和持续交付唯一的不同,就是手动确认的环节没有了,每次代码从分支合并到主干,在自动化测试通过后,会直接部署到生产环境,不需要人工确认。

但是,持续部署要想做好,还是很有挑战的一件事,毕竟从代码合并和生产环境的部署,如果没有人工干预仅仅依然于自动化测试,这对自动化测试的覆盖率和稳定性要求非常高。尤其在开发新功能时,还需要引入新的自动化测试代码,可能会导致测试不全面。

当然对于新功能可能导致的不稳定问题也有解决策略,就是把新功能用功能开关(Feature flag)隐藏起来,设置特定的 Cookie 或者 Header 才打开,到生产环境后人工再测试一遍,通过后再打开,如果没通过,就继续修复继续持续部署。

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

  • 我们通常会把软件研发工作拆解,拆分成不同模块或者不同团队后进行编码,编码完成后,进行集成构建和测试,这个从编码到构建再到测试的反复持续的过程,就叫做“持续集成”
  • “持续集成”一旦完成,则代表产品处于一个可交付状态,但并不代表这是最优状态,还需要根据外部使用者的反馈逐步优化。这里的使用者可能是真正的用户、测试人员、产品人员等等
  • 在“持续集成”之后,获取外部对软件的反馈再通过“持续集成”进行优化的过程就叫做“持续交付”,它是“持续集成的自然延续”

那“持续部署”又是什么呢?

  • 软件的发布和部署通常是最艰难的一个步骤
  • 传统安装型软件,要现场调试,要用户购买等等,其难度可想而知。即使是可达度最高的互联网应用,由于生产环境的多样性(各种软件安装,配置等)、架构的复杂性(分布式,微服务)、影响的广泛性(需要灰度发布)等等,就算产品已是待交付的状态,要真正达到用户可用的标准,还有大量的问题需要解决。
  • 而“持续部署”就是将可交付产品,快速且安全地交付用户使用的一套方法和系统,它是“持续交付”的最后“一公里”

可见:

  • “持续交付”是一个承上启下的过程,它使“持续集成”有了实际业务价值,形成了闭环,而又为将来达到“持续部署”的高级目标做好了铺垫。
    虽然从概念上你可以这样理解,但往往是从“持续部署”(自动化发布)开始推进“持续交付”,这才是一条优选的路径。

持续交付也通常以“发布流水线”的方式来解释,即研发团队从开发,到测试,再到部署,最终将产品交付给最终用户使用的过程。如下图:

在这里插入图片描述

它的关注点可以概括为:持续集成构建、测试自动化和部署流水线

该不该应用持续交付?

不管是敏捷开发还是瀑布开发,都可以去应用持续交付。有如下好处:

  • 尽快暴露问题:Martin Fowler 说过,“持续集成并不能消除 Bug,而是让它们非常容易发现和改正。”自动化测试,可以保证很多问题在合并到分支之前就能被发现;每次合并后就部署到测试环境,也能让测试人员尽早介入,及时发现问题。
  • 极大提升效率:持续交付让开发过程中从代码合并,一直到最终部署,都实现了自动化,能极大程度上提高效率。
  • 提升质量:每次合并之前都需要通过自动化测试,因此错误会少很多。
  • 降低项目成本:在最初搭建持续交付环境的时候,是要投入一定成本的,但是从长远看,开发效率提升了,代码质量提高了,反而是对降低项目的整体成本有帮助的。

虽然现在持续交付还不够普及,但未来就像源代码管理一样,成为开发团队的标配。现在大都已经普及了持续交付,还会有专门的团队负责持续交付工具的开发和维护。对于中小厂,一般不需要自己开发持续交付工具,可以基于开源工具搭建,或者购买托管的持续交付工具,一样可以很好满足持续交付的需求。

如何搭建持续交付环境?

要搭建好自己的持续交付环境,其实并不算太难,已经有很多持续集成工具和教程帮助我们做这些事。

准备工作

根据前面对持续交付的说明,要想搭建自己的持续交付环境,并不是简单找一个持续集成工具一搭就可以工作了,而是还需要做一些准备工作。

我们先来看持续集成部分,持续集成相对要求简单:

  • 需要有源代码管理工具,比如说git、svn,因为持续集成工具需要从统一的源代码仓库获取代码
  • 需要写自动化测试代码,因为持续集成有一个很重要的条件,就是自动测试必须通过(自动化测试覆盖率,可以逐步提升,不要求一步到位。所以可以先把自动化测试写起来,然后在开发过程中逐步增加覆盖率。)

、持续交付相比持续集成要求更高,因为整个过程需要高度自动化。要实现持续交付,项目必须满足如下条件:

  • 对代码构建的过程可以反复进行,并且每次构建的结果都是一致的、稳定的
  • 所有环境的配置都存在于源代码管理工具中,不仅仅是代码
  • .需要自动创建针对于不同环境的发布包
  • 所有环境的部署发布步骤都必须是自动化的

上面这些要求,最难的部分其实就是自动化打包和自动化部署到各种环境,因为每套程序都不一样,每个服务器环境也不一样,这是必须要各个团队针对自己的项目情况去解决的问题。

选择合适的持续集成工具

持续集成工具现在已经有很多选择,有开源的、商业的,有线上托管的,还有自己搭建的。主要的持续集成工具有这些:

  • Jenkins应该是目前最好的开源持续集成工具,可以自己搭建,插件非常丰富,可以满足绝大部分项目的需要。相对使用难度要高一些,需要花一点时间学习。
  • Go CD是 ThoughtWorks 公司出品的持续集成工具,可以免费使用。
  • Travis CI是一个老牌的托管的商业 CI 系统,和 Github 集成的非常好,尤其是开源项目,可以免费使用。
  • GitLab CI是 Gitlab 推出的持续集成工具,可以自己搭建也可以使用它的在线托管,价钱便宜。
  • Azure Pipelines是微软的持续集成平台,可以自己搭建也可以使用它的在线托管,和微软的开发语言和服务集成很好。

在选好你要用的持续集成工具后,就需要根据工具的说明去搭建。

总结

  • 持续集成,就是持续频繁地将代码从分支集成到主干,并且要保证在合并到主干之前,必须要通过所有的自动化测试。
  • 持续交付,则是基于持续集成,在自动化测试完成后,同时构建生成各个环境的发布包,部署到测试环境,但生产环境的部署需要手动确认。
  • 持续部署,是在持续交付的基础上,对生产环境的部署也采用自动化。

要搭建持续交付环境,首先需要做好准备工作,例如自动化测试代码和自动部署脚本;然后要选择好持续集成工具;最后按照选择的持续集成工具来实施。

问题

基于主分支开发 VS 每人基于自己的分支开发完再合并回主分支 哪种效率更高

对于软件工程来说,很多问题,并不是只有唯一解,即使是最佳实践,也得看适用的场景和团队。
无论是基于主干还是分支开发,有两点需要注意的:

  1. 就是一定要有一个稳定的分支,可以随时发布的那种,至于是叫master还是叫release并不重要。
  2. 合并之前要有代码审查和自动化测试(配合CI)。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值