目前IT行业中,似乎“要不要做持续集成?”已经不再是讨论的焦点,取而代之的是“如何进行持续集成?”。在前一篇文章中,我介绍了Cruise团队持续集成的演进过程。在最后,还曾提及Cruise团队的持续部署。本文将结合团队的实际情况,与大家分享持续部署的实践心得。
“最后一哩”问题
持续集成解决了软件开发中的部分问题,但还有更为重要的一部分有待解决,即“通过什么样的方法,可以让软件尽快地在真正的生产环境下运行,从而实现软件的价值”。在软件开发过程中,“从功能开发完成开始直到将其部署至生产环境中正式运行”这一阶段被称为“最后一哩”。如果从一开始就对产品发布足够重视的话,那么这“最后一哩”可能只需要几分钟,甚至几秒钟就完成了。然而,事实上大多数项目在这一阶段会花上几个星期,更有甚者可能会是几个月。
为什么会这样呢?对于复杂软件来说,无论什么环境中的部署(测试环境,试运行环境,还是生产)都很困难。当软件第一次被部署到非开发环境去测试,或者当软件功能及其环境有较大变化时,通常都会暴露出很多问题。而在做用户验收测试时,常常会发现更多的问题,例如不能满足非功能需求,用户操作不方便,功能与用 户真正需要的东西相差太远等等。而开发团队只有修复这些缺陷后,才能再次部署测试。于是,这个过程会不断反复,直至该软件足够稳定,才可以部署到生产环境中。
即然部署到测试环境都这么困难,那么在生产环境中部署的风险岂不会更大吗?而且,更为严重的是:当生产环境部署出现问题时,摆在你面前的选择就所剩无几啦(通常是回滚到以前的状态,而“回滚”这段时间的停机成本是相当高的)。
上述原因就会导致大多数组织对产品的发布采用“保守策略”,即降低软件的发布频率,这也导致两次发布之间的版本特性差异相对较大。这样一来,发布风险并未因发布间隔时间加长而降低,反而更高了。当各方面的因素结合在一起时,软件发布这一环节就变得昂贵而又缓慢啦。而通常“发布过程与频率”决定了产品在市场中的位置。
那么,如何更好地解决“最后一哩”这一问题呢?实现持续部署! 即将持续集成实践扩展到整个软件生命周期频繁且规律性地自动构建代码并将其部署到测试环境中,然后通过一系列的测试,选择适当的版本部署到预演环境中试运行,最后选择稳定的版本部署到生产环境中,从而使开发团队尽早从最终客户那里得到反馈,而最终客户尽早得到软件的价值。
“持续部署”源于部署时的痛苦
在使用Cruise来构建Cruise本身以后的第二周后,当我们想再次升级它时,因没有事先考虑好升级方式,结果用了两人天才把它搞定。从那以后,我们就开始了Cruise的持续部署之旅。
持续部署环境
目前Cruise的研发环境中,有一个被称为“UAT(User Acceptance Testing)”的测试环境,目前它由一台Cruise Server和近20台Agent组成,用于Cruise团队自身的持续集成与部署管理。还有另一个被称为“Production”的预发布生产环境,它由一台Cruise Server和近70台Agent组成,由多个项目组同时使用。“Production”环境是真实的生产环境,部署失败,就意味着损失。因此,虽然部署工作可以通过自动化脚本完成,但我们还是在“UAT”和“Production”两个Stage之前加上了人工开关(manual approval),如下图所示。前三个Stage全部是自动触发,其后全部为手工触发。每个待发布的版本都会先被部署到UAT环境中,实际上也就做了试 运行,如果该版本稳定,则部署到“Production”环境中。这样就使部署风险尽在掌控之中。
让持续部署成功的要点
1. 充分而广泛的自动化测试覆盖
目前我们的测试包括单元测试、End2End测试、功能测试和性能测试。其中单元测试、End2End测试及功能测试都在同一个 Pipeline中,每次代码提交都会运行这些测试。而性能测试在另一个Pipeline中,用于每次部署后,收集UAT环境和Production环境的性能指标。由于部署频率足够,我们可以掌握性能数据的微小变化,据此来采取相应的优化措施。
写单元测试已经成为不争的事实,自不必说。另外,由于Cruise与很多版本管理软件打交道,这里所说的End2End测试是指与这些外部接口的测试。而功能测试是指将Cruise Server和Agent真正在测试机器上运行起来后,再运行TWIST自动化测试套件。我们对功能测试的原则就是每个Story都要有功能测试覆盖,QA与开发人员共用编写功能测试用例,由开发人员实现之,而且功能测试要让真实的Cruise Server和Agent进行通信的基础上进行。TWIST是我们公司的另一款产品,用于自动化功能测试,其测试编辑界面如下所示:
2. 尽可能短的测试反馈时间
尽管测试数量较大,测试的绝对运行时间较长,但结合Cruise本身提供的并行运行特性,团队成员胡凯,Derek和李彦辉自行开发的测试负载均衡工具(Test-load-balancer)将所有测试分成若干份,Cruise将其分配到Agent集群中同时运行,使单元测试或其它测试在可接受的相对时间内完成(单元测试在15分钟之内,功能测试在30分钟之内)。近期还将增加数个Agent,以便继续缩短测试需要的时间。
3. 部署过程自动化
当部署复杂软件时,都会使用人工过程,而且可能会花上几天的时间。而这种部署过程通常比较复杂,而且很难可靠地重复操作。因此,人们会写一些文档帮助这一过程,但文档常常更新不及时。有时,还需要几个关键性人物同时在场才能完成。
当每次由不同的人员进行部署操作时,出错的概率就增加,所以要尽可能少的人工步骤。
在Cruise的Pipeline中,尽管由人来触发两个环境中的部署,但部署过程本身是自动化的。在部署过程中,Cruise的安装包会自动关闭服务器,更新自身程序和升级数据库,然后再重新启动。所有的Agent也会以Server为准,自动更新到与其相同的版本,而不必人工去升级每个 Agent(每次为70个Agent的手动升级也是很大的成本,所以我们做了自动升级这个特性)。
原文转自:http://kb.cnblogs.com/page/157115/