持续交付模式

发表于:2014-04-11来源:博客园作者:Jonathan点击数: 标签:持续交付
当你有了持续集成需要的构建服务器和脚本之后,下一个问题肯定是:“我们该拿这些构建版本怎么办?”持续交付,以自动化或半自动化方式,将构建版本从一个环境提送(promote)到更接近实际生产的交付准备环境;这常常是公司在这方面演进的下一步。

  英文原文:Patterns for Continuous Delivery

  当你有了持续集成需要的构建服务器和脚本之后,下一个问题肯定是:“我们该拿这些构建版本怎么办?”持续交付,以自动化或半自动化方式,将构建版本从一个环境提送(promote)到更接近实际生产的交付准备环境;这常常是公司在这方面演进的下一步。

  任何规模的公司都可以实施持续交付,但是具体流程会根据公司具体情况差异很大。显而易见,四人全能团队的需要,与大规模、多团队、配备正式QA和设备精良的产品支持部门这样的公司,二者一定有很大差别。本文没有试图提出万能方案,而是覆盖多种场景和选择。

  选择持续交付工具集

  为持续交付选择工具集,是最不重要的决策。当你制定出工作流程之后,只需要选择相匹配的工具集即可。考虑到初始设置和配置的工作量,花几天时间构建自己定制的工具也不是非理性选择。

  更重要的是,这样做没有锁定的风险。跟选择版本控制系统不同,你可以使用多种持续交付工具,而且可以互相之间自由切换。QA团队从开发人员那里拉出构建版本使用一种工具,向准备服务器推送时使用另一种工具,这样的事情也有所耳闻。

  基线场景

  在基线场景中,我们要以有限的资源找出公司中的模式。像由3到4人构成的IT部门,常常兼做开发和系统管理。这样规模的团队常常支持中小型业务,特别是不以技术为主业务的公司。大型公司也有可能这样组织,把人分成多个、很可能是互相独立的小组,各小组之间也没有交互。

  在真正开始进行持续交付之前,需要做一些必要的设置工作。首先,最重要的是要有版本控制系统,以及与之匹配的构建服务器。这第一台构建服务器将会是你的持续集成服务器,它要保证每次签入动作都能成功构建。一般来说,你需要一个“现成”的构建服务器担当此任。能够监控签入动作还要自动初始化构建,要想手工开发这样的东西,真正操作起来常常要比听起来难得多。即使可以在版本控制系统中加入触发机制,完成诸如失败构建通知这样的功能也不值得花太多功夫。

  即使在资源有限的作坊式公司,交付准备服务器(staging server)也是持续交付的必要组成部分。交付准备服务器应该尽可能模拟出生产环境。“你有多少预算”常常是首要问题。如果你的生产环境有价值几十万美元的数据库服务器,很可能你无法负担搭建一个同样的交付准备服务器。而且可能你也不想这么做。

  在模拟生产环境时,有一个常见错误:过高匹配硬件环境。假如你的生产环境每秒处理100个请求,如果为交付准备服务器购买同样硬件,但测试时每秒只执行几个请求,你的结果就是有问题的。理想情况下,为了模拟生产环境请求,你还应该购买并设置负载服务器,但这么做成本太高,而且耗费时间。对于这种规模的团队,降低交付准备服务器处理能力是更佳策略。

  另一个常常忽略的需求,是构建的版本化。必须有某种唯一的识别机制,保证可以区分开每个构建和其他构建版本。如果针对单一的公共主干代码,简单的时间戳或是自增长版本号也就够了。本文后面会讨论更复杂的场景。

  结构

  有了上面列出来的部件,现在你的环境应该跟下面的图很像:

  交付策略

  构建服务器编译代码,交付准备服务器等候接收构建结果,有了这二者之后,下一步就是决定你的部署策略。小团队有两种选择:“签入时交付”和“定时交付”。

  签入时交付

  “签入时交付”策略的优势在于马上产生的满足感。根据代码库的规模,从签入新功能代码到能够在交付准备服务器上测试,一两分钟就够了。

  这种方式的主要问题在于:交付准备服务器会被蹂躏得不稳定。很多时候,我见到有人试图测试某个功能,突然新的版本推到交付准备服务器上了,破坏了正在运行的测试。更糟糕的是:交付准备服务器常常作为演示服务器使用,在某些重要的演示时,很可能出现严重的后果。

  代码混乱是另一个问题。比如,如果三次签入在很短的时间内先后进行,那么可能触发三个构建、交付周期,实际上只有最后一次才是必要的。极端情况,这会带来很大混乱,交付部署环境将无法有充足的时间展示自己的功用。不过,大多数构建服务器都有选项,可以延迟构建的开始,或是在给定时间间隔内避免多次构建。

  定期交付

  定期交付策略更易于预测。所有人都知道交付何时启动,并可以规划自己的代码签入是在交付之前还是之后进行。典型做法是一天构建/交付一次或两次。

  每日构建的缺点在于,它会给工作环境带来不必要的压力。开发人员会发现自己要赶着在构建截止时间之前完成一次签入。在每日深夜构建,这时开发人员应该不在工作,可以减轻压力,但也意味着除非到第二天,他们无法执行第二层测试。

  当我们开始使用“每日构建”这样的词汇时,很容易忘记我们实际上不是在谈论构建。我们真正在谈论的是完整的构建、交付周期。有了持续集成,如果构建失败,你马上就能知道。接下来是要修复问题,还是要回滚签入,就很简单了;只要规划好的交付完成了,软件就已经准备好部署到生产环境。

  部署到生产环境

  该场景的假设是:实在没人能够完成任何特定版本前要做的大量测试工作。只要交付准备服务器上的检查完成,构建版本就会直接提送到生产环境中。但即使如此,也有多种选项,各有其妥协之处。

  从交付准备阶段提送

  将经过验证的构建版本从交付准备服务器直接提送,是常见的选择。其优势在于高度确定性。理论上,测试一个版本的构建、然后错误地部署另一个版本,这样的事情不可能发生。写脚本把文件从交付准备服务器拷贝到生产环境,也很容易。

  但像很多事情一样,理论跟现实总是有差距的。有了到交付准备服务器的自动化推送,很可能出现这样的情况:测试完成,去倒一杯咖啡,回来后工作针对的构建版本可能就完全不同了。更糟糕的情况是:构建代理会开始覆盖交付准备服务器上的文件,而这时这些文件正在推送到生产环境服务器上。

原文转自:http://kb.cnblogs.com/page/117932/