快速验证.运行

12009

概述

运行,是指将达到质量要求的软件包部署到生产环境或交到用户手中,并使之为用户提供服务。每次进行新版本软件的部署发布时,我们都不希望影响用户的正常使用。因此,如何让用户在无感知的情况下完成软件版本的升级更新是互联网时代最为重要的课题。即便是最传统的金融行业也在不断寻找更优的解决方案,在保证事务安全和数据一致性的前提下,优化用户体验。

这一环节是开发团队与运维团队之间发生冲突最多的环节,也是重复性手工操作最多的环节之一。在这一方面,团队应该不遗余力地进行改进和优化,将人从重复性体力劳动中解放出来。

高频发布

趋势

现在,世界领先的互联网公司都在以“频繁发布”的模式更新它们的软件产品。例如,早在2011年5月,亚马逊公司的月度统计数字表明,平均每11.6秒就触发一次软件部署操作,当月最高部署频率达到每小时1079次之多。平均1万台服务器会同时收到部署请求,而最高一次是3万台服务器同时执行一个部署操作。

在2017年,Facebook公司每天对其网站推送多次部署,而其移动应用客户端每周向应用市场推送一次,每天面向内部员工发布最新的内部全员体验版本,并且面向十万和百万用户推送Alpha版和Beta版。

当然,这些发布中并不全是功能发布,当然也会包含缺陷修复。随着部署频率的提升,以及总代码量和提交次数的提高,严重缺陷数量并没有随之升高。尽管严重程度为中级和低级的缺陷数量有所上升,但考虑到开发人员数量的增长、网站系统复杂性的提升以及公司对待软件质量的观点,这是可以接受的程度。

收益与成本

在高频发布模式中,每次发布的内容量通常都会少于在低频发布中每次发布的内容量(显然一天可以完成的功能比十天的少)。为什么这么多公司都在向“高频发布”这个方向迈进呢?高频发布的收益有以下几个。

  • 有更多的机会与真实用户互动,从而快速决定或调整自己产品前进的方向。
  • 由于每次变更规模较小,软件系统没有剧烈的变化,从而降低部署风险。
  • 单次部署成本降低,且趋于恒定。因为频繁的部署操作会令人感到痛苦,就会有动力做很多自动化设施建设,从而减低成本和精力。
  • 出现问题易定位、易修复,且能够快速更正。

高绩效的团队比低绩效团队相比:

  • 其代码发布频率高出46倍;
  • 从代码提交至代码部署所用时间缩短为1/440;
  • 平均故障恢复时间缩短为1/96;
  • 变更故障率降低为1/5。

上述收益来自成熟且自动化的部署与发布操作。如果仍旧坚持低频发布模式所用的研发管理方法,则强行执行高频发布会带来较高的迭代成本。例如,某团队原来每个月手工发布一次,现在决定每周发布一次。暂且不讨论每个版本的质量验证成本会如何变,假设仍旧采用原有手工模式,那么每月的工作量就是原来的4倍。而且,在发布周期缩短后,原来工作模式中并不占用太多成本的操作(如编译时间、测试工作强度等)都会变成较为突出的矛盾。

然而,无论怎样,我们都无法100%消除发布风险。我们要做的是不断寻找降低发布风险的方法。

降低发布风险

蓝绿部署

准备两套完全一致的运行环境,其中一套环境作为正式生产环境,对外提供软件服务。另一套环境作为新版本的预生产环境,部署软件的新版本,并对其进行验收测试。当确认没有问题后,将访问流量引流到这个新版本所在的环境中,作为正式的生产环境,同时保持旧版本所在环境不变。直至确定新版本没有问题后,再将旧版本所运行的环境作为下一个新版本的预生产环境,部署未来的新版本。

当然,这是一个非常理想的情况。现实中,数据库复制的时间成本较高,而且空间成本也较高。因此,很多蓝绿部署方案会使用相同的数据库服务,只是软件的部署使用不同的两套环境,如图12-7所示。在这种情况下,同一个数据存储格式必须对新旧两个软件版本做兼容性处理,使其可以同时服务于两个软件版本对数据的操作。

另外,蓝绿部署中还有一个需要处理的问题。也就是,当切换发生在用户的一次业务操作过程当中且涉及事务处理时,如何处理数据的一致性问题。一般来说,切换并不是在瞬间完成的。在切换的过程当中,新的请求直接被导向到新版本的环境,不再允许访问旧版本的环境。对于那些在切换发生时尚未返回结果的旧有请求,旧版本的环境允许其访问完成,之后不再接收新的请求即可。

滚动部署

从服务集群中选择一个或多个服务单元,停止服务后执行版本更新,再重新将其投入使用。循环往复,直至集群中所有的服务实例都更新到新版本。与蓝绿部署相比,这种方式更加节省资源。因为它不需要准备两套一模一样的服务运行环境。因此,服务器的成本就相当于少了一半。

当新版本出现问题时,这种滚动部署方式无法像蓝绿部署那样只要直接通过前面的流量负载均衡器直接切换回旧环境即可,而是必须要对其中已部署新版本的服务器进行回滚。另一种方式就是快速修复问题,生成第三个版本V3,然后马上发起一次V3的滚动部署。此时,服务集群中就可能会有V1、V2和V3这3个版本存在。

金丝雀发布与灰度发布

泛指通过让一小部分用户先行使用新版本,以便提前发现软件存在的问题,从而避免让更多用户受到伤害的发布方式。因为仅有一小部分用户使用,所以造成的影响也比较小。

“金丝雀发布”的名字来自矿工下井的一个古老实践。17世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。当时,采矿工人为了保障自身的安全,每次下井工作时都带上一只金丝雀。如果井下存在有害气体,在人体还没有察觉到有害气体时,金丝雀就会因无法抵抗瓦斯气体而死亡。此时,矿工就会知道井下有毒气,马上停止工作,回到地面。

“灰度发布”是指将发布分成不同的阶段,每个阶段的用户数量逐级增加。如果新版本在当前阶段没有发现问题,就再扩展用户数量进入下一个阶段,直至扩展到全部用户。它是金丝雀发布的一种延伸,也可以说,金丝雀发布是灰度发布的初始级别。对于“划分多少个阶段,每个阶段的用户数量是多少”,要根据产品状态自行定义。

暗部署

功能或特性在正式发布之前,将其第一个版本部署到生产环境,以便在向最终用户提供该功能之前,团队可以对其进行测试,并发现可能的错误。“暗部署”中的“暗”字,是针对“用户无感知”这一点而言,这可以通过开关技术来实现。

例如下面这个场景:某个互联网公司重新开发了一个在线新闻推荐算法,希望能够为用户推荐更多的优秀内容。但是,由于算法复杂,公司想知道在大量的真实用户访问情况下,这个算法的性能到底如何。这时要如何做呢?

我们可以为这个算法配置一个开关,并将其部署到生产环境中。当这个开关打开时,就会有流量进入这个算法。但是用户并不知道他用的是旧算法,还是新算法。如果这个算法的性能不够好,我们可以马上关闭这个开关,让用户使用原来的旧算法。

小结

在一些业务场景下,我们的确无法直接高频地对外发布软件。但是,如果我们能够使用本章介绍的方法持续向预生产环境进行发布与部署,就可以尽早获得软件的相关质量反馈,从而减少正式发布后的风险。如果我们能够将每次发布的平均成本降低到足够低,那么将会直接改变团队的产品研发流程。