0%

优秀管道的5个特点

优秀交付管道的5个特点

持续交付(Continuous Delivery)不仅提升了开发团队的自信,并且将交付新功能变为商业决策,使产品团队也获益匪浅。

交付管道(delivery pipeline)是持续交付的核心。它显示了团队如何将变更交付到生产,并且为项目质量把控提供了一站式的服务。

image-retina_ready

优秀管道有一些关键的特点需要尽量达成;本文会列举我研究过的5个。当然这并不是一个完整的列表,每个项目都应该考虑各自的特点。但是我工作过的项目,少了某个特征,会给团队造成麻烦。

  1. 能够提高质量产品

    大部分管道都会包括一系列的验证,从 代码静态分析 到 完整的UI测试。并没有明确准则定义哪些该包含在管道中,我认为如果能够提供有效的质量反馈,就应该被包含在管道中

    然而,有一些验证经常被团队忽略,像 cross-functional tests。这些测试通常跟性能有关,但也可以测试应用能承受的负载以及暴露安全缺陷。

    为了使团队获取每个修改的这方面反馈,这些测试(cross-functional tests)应该被包含在管道中,并且尽可能自动执行。即使公司对所有产品都会进行负载测试以保证产品的每个部分都能应对流量,团队也应该将小型的负载测试作为管道的一环。

    Cross-functional tests通常在管道中需要做一些特殊处理。如果其中一项测试失败,有时候并不需要停止整个过程。假设产品的性能低于了某个阈值,并不意味它不能工作了。

    cross-functional checks应该指导团队下一步的行动而不是使构建失败。这表示测试的功能可以运行;所以团队必须考虑项目,决定什么样子的交叉功能测试应该替换并且怎么生效。

    回到性能降低的例子,团能能够追踪到上次修改后,应用的哪一部分变慢。能够调查出可能的因素,接下来我们进入第二个因素。

  2. 可以提供快速而有效的反馈

    将质量检测加入到管道中是非常棒的,同时团队也需要接收每次变更的反馈,并且这些反馈需要迅速。

    尽快反馈,我们应该遵循 Fail-Fast 原则。所以,相对快速的任务,例如代码静态分析(code lint)或者单元测试(unit tests),应该在前边运行;手动测试和性能检查,尽可能在我们确定代码有效后进行。

    并行运行任务,对减少获取反馈的时间也有很大帮助。

    假设,你的管道:代码静态分析(需要2分钟),单元测试(需要另外2分钟),集成测试(需要5分钟)。串行管道情况下,设想下最糟糕的场景,一次提交使造成三个任务都失败,需要花费24分钟,才能得到一次成功的构建。

    同样的情况,如果并行的执行任务,你的团队紧紧需要花费5分钟获取反馈,另外5分钟得到一次成功的构建。

    像探索性和可用性测试等手工步骤,反馈周期很长。因为这依赖人工使用系统,通常作为最后一个执行步骤。但是仍然应该是反馈中的一环。

    对于自动化的步骤,我们分辨出哪个步骤耗费时间长,然后想办法改进。

    另外一个关键因素是能够提供高效,准确的反馈。如果管道中的一个job,负责很多事情,当失败时,团队很难确定具体哪里失败了并且又可能隐藏信息。保持比较小的步骤,清晰的错误信息,可以提高团队查找bug的效率,防止团队对管道技术失去信心-a.k.a. just re-run the build - it should go green.

  3. 减少人工的介入

    我们非常喜欢自动化,在交付软件的过程中,仍然需要人工的介入。但是我们可以将人工介入最小化,更高效。

    在任何的人工测试之前,最好能够保证,在一个与生产环境相似的环境中,所有的自动化步骤已经成功。这种方式不仅测试了应用,并且测试了配置。可以节省花费在解决环境问题的时间。

    大部分花费几天,几周甚至几个月进行人工测试的情况,往往是由于测试人员与开发团队没有或者仅有很少的合作。如果所有的部署都需要经过一个完整的质量管理部门,大量的团队时间就被消耗。

    这里的意思并不是说人工测试(manual tests)是二等公民,而是人们应该合作,使过程高效。参照 ‘Amigos’ 策略.

    划分功能的团队,通常不清楚其他团队的工作,所有每个人尽力把自己的事情做好。因此,每个功能都会被完整测试,造成浪费,如 the testing cupcake anti-pattern 所说。

  4. 使用相同的过程和包

    不管之前团队做过多少测试,应用将要上线的时候,每个人还是会有些担心。我们如何提升对我们部署的自信呢?持续交付的方式就是保证从开始到生产环境,都使用同样的包执行所有的过程。

    一个二进制包在这里表示要被部署到一台服务器的包。有可能是一个系统包,有特殊标签的源码,一个docker镜像等。不管是什么,一个好的管道会使用完全一样的包部署到不同的环境中,在预发布环境中也是使用同样的包加速生产或者简单的QA测试用作探索测试。

    另外一个关键点是使用相同的过程部署包。如果有自动化脚本部署到QA环境,也应该使用他部署生产以及其他环境。如果你部署到生产是手动部署,有很大的概率会出现人为错误,简单的打字错误到忘记一个启动服务器前的关键步骤。

    任何环境间的不同都应该抽取到配置文件中作为自动化脚本的输入。这样你可以保证部署过程在生产环境也会生效,虽然配置的错误也时有发生。

    自动化部署的过程,对你的团队是持续交付的好开端。如果你可以说服人们使用自动化脚本部署所有环境,CD的优势也会开始显示,引起大家的关注。但是请记住,自动化部署只是一个开始。

  5. 能够在任何时候交付任何版本

    持续交付的必杀技不是每天部署或者自动将每次提交上线生产,而是不需要经过软件研发团队的协助,使商业能够决定何时上线一个功能。由产品团队决定,是否每天,每小时或每月部署。

    为了实现这个目标,管道必须(为产品团队)提供一种便捷的方式,可以在任何时间,发布任何版本。维持这样一个回滚策略有可能是个噩梦,所以需要团队根据项目,做出最佳的选择。或许更好的选择是,仅仅提供回滚到之前1,2个小版本的能力。

    这里的关键是,发布新的版本跟回滚到上一个版本一样简单,以防有一个严重的问题。理想情况下,你总是可以前滚和借助功能切换关闭一个崩溃功能。如果想了解更多功能切换,参照文章:Enabling Trunk Based Development with Deployment PipelinesOn DVCS, continuous integration, and feature branches

    回滚时,最大的困难是保证数据的完整(integrity)。理想情况下,团队应该避免破坏性变更,保持系统对之前版本的数据兼容性。某些场景,数据库备份有可能可行,但是回滚期间保存的数据会丢失。参照: Refactoring Databases

    将部署任何版本变得便捷不是一个简单的任务,但是不仅仅对产品团队有好处,对开发团队也有帮助。设想一下,你半夜接到电话,生产环境中一些功能崩溃。你登录,访问,但是找不到什么有用的信息。相比你将一整夜花在寻找这个bug,有可能影响你第二天。一个更优的选项是“好吧,暂时将系统回滚,明天深入调查”。

    我希望本文能够帮助到你和你的团队,可以帮助提升你的管道。再次强调,这不是一个完成的广泛列表,一个优秀的管道需要包括。想要获取更深入的理解,可以参照文中列出的其它文章。