1 发布之痛
相信每个程序员都曾经经历过,或正在经历过发布的痛苦,每个发布日的夜晚通常是灯火通明。在现在互联网公司较高的发布频率之下更是放大了这种痛苦,多少正值青春年华的程序员为此白了发、秃了头!让程序员经历发布痛苦的原因有很多,其中之一就是发布方式。
发布造成系统故障影响系统可用性的最大原因之一。因此大多数的公司会选择在用户量最小的深夜进行发布,这就造成了每到发布日就有一大堆黑眼圈的程序员熬夜坐等发布,但其实有了一些好的发布方式也许就不必如此。
我曾经带过两家公司,这两家公司团队的对于发布时间的看法则孑然不同,第一家公司的总是担心发布会对用用户造成影响,因此每次发布都会选择深夜进行发布。而另一家公司则认为应该在用户流量最大的时候进行发布,这样系统问题则可以尽早的暴露出来。造成这两种的结果我分析有很多原因。开发人员信心、交付质量、资源工具、发布方式……我们今天就来看看一些常用的发布方式。
2 常用的发布方式
2.1 蛮力发布
顾名思义,这种方式简单而粗暴!直接将新的版本覆盖掉老的版本。其优点就是简单而且成本较低,但缺点同样很明显,就是发布过程中通常会导致服务中断进而导致用户受到影响,这种方式比较适应于开发环境或者测试环境或者是公司内部系统这种对可用性要求不高的场景,有些小的公司资源稀缺(服务器资源,基础设施等)的时候也会采用这种方式。比如我的第一家公司一开始的规模较小的时候,通常会选择一个夜深人静、访问量小的时候,悄悄地发布。
2.2 金丝雀发布
金丝雀发布是灰度发布的一种。灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。即在发布过程中一部分用户继续使用老版本,一部分用户使用新版本,不断地扩大新版本的访问流量。最终实现老版本到新版本的过度。由于金丝雀对瓦斯极其敏感,因此以前旷工开矿下矿洞前,先会放一只金丝雀进去探是否有有毒气体,看金丝雀能否活下来,金丝雀发布由此得名。
发布过程中,先发一台或者一小部分比例的机器作为金丝雀,用于流量验证。如果金丝雀验证通过则把剩余机器全部发掉。如果金丝雀验证失败,则直接回退金丝雀。金丝雀发布的优势在于可以用少量用户来验证新版本功能,这样即使有问题所影响的也是很小的一部分客户。如果对新版本功能或性能缺乏足够信心那么就可以采用这种方式。这种方式也有其缺点,金丝雀发布本质上仍然是一次性的全量发布,发布过程中用户体验并不平滑,有些隐藏深处的bug少量用户可能并不能验证出来问题,需要逐步扩大流量才可以。
2.3 滚动发布
滚动发布是在金丝雀发布基础上进行改进的一种发布方式。相比于金丝雀发布,先发金丝雀,然后全发的方式,滚动发布则是整个发布过程中按批次进行发布。每个批次拉入后都可作为金丝雀进行验证,这样流量逐步放大直至结束。
这种方式的优点就是对用户的影响小,体验平滑,但同样也有很多缺点,首先就是发布和回退时间慢,其次发布工具复杂,负载均衡设备需要具有平滑的拉入拉出能力,一般公司并没有资源投入研发这种复杂的发布工具。再者
发布过程中新老版本同时运行,需要注意兼容性问题。
2.4 蓝绿部署
蓝绿部署,是采用两个分开的集群对软件版本进行升级的一种方式。它的部署模型中包括一个蓝色集群 Group1 和一个绿色集群 Group2,在没有新版本上线的情况下,两个集群上运行的版本是一致的,同时对外提供服务。
系统升级时,蓝绿部署的流程是:
- 从负载均衡器列表中删除集群Group1,让集群 Group2 单独提供服务。
- 在集群 Group1 上部署新版本。
- 集群 Group1 升级完毕后,把负载均衡列表全部指向 Group1,并删除集群 Group2 ,由 Group1 单独提供服务。
- 在集群 Group2 上部署完新版本后,再把它添加回负载均衡列表中。
这样,就完成了两个集群上所有机器的版本升级。
蓝绿部署的优点是升级和回退速度非常快,缺点是全量升级,如果V2版本有问题,对用户影响大再者由于升级过程中会服务器资源会减少一半,有可能产生服务器过载问题,因此这种发布方式也不适用于在业务高峰期使用。
2.5 红黑发布
与蓝绿部署类似,红黑部署也是通过两个集群完成软件版本的升级。当前提供服务的所有机器都运行在红色集群 Group1 中,当需要发布新版本的时候,具体流程是这样的:
- 先申请一个黑色集群 Group2 ,在 Group2 上部署新版本的服务;
- 等到 Group2 升级完成后,我们一次性地把负载均衡全部指向 Group2 ;
- 把 Group1 集群从负载均衡列表中删除,并释放集群 Group1 中所有机器。这
这样就完成了一个版本的升级。可以看到,与蓝绿部署相比,红黑部署获得了两个收益:一是,简化了流程;二是,避免了在升级的过程中,由于只有一半的服务器提供服务,而可能导致的系统过载问题。但同样也存在全量升级对用户的影响问题,也带来了一个新的问题,就是发布过程中需要两倍的服务器资源。
2.6 功能开关
这种发布方式是利用代码中的功能开关来控制发布逻辑,是一种相对比较低成本和简单的发布方式。研发人员可以灵活定制和自助完成的发布方式。这种方式通常依赖于一个配置中心系统,当然如果没有,可以使用简单的配置文件。
应用上线后,开关先不打开,只待一声令下,可以全量打开开关,也可以按照某种维度(公司ID,用户ID等)分批打开开关进行流量验证,如果有问题,则随时关闭开关。
这种方式的优势在于升级切换和回退速度非常快,而且相对于复杂的发布工具,成本较为低廉。但是也有很大的不足之处,就是开关本身也是代码,而且是与业务无关的代码,对代码的侵入性较高,也必须定期清理老版本的逻辑,使得维护成本增加。
3 小结
这篇文章介绍了目前常用的一些发布方式,每种发布方式各有其优缺点。但其实在真正实践过程中这些发布方式往往是根据具体的情况来结合使用的。主要可以通过升级回退速度、成本、对用户影响三个方面来考虑。
比如在我最开始的小型公司里,公司业务小,服务器资源也不足,甚至连最基础的负载均衡服务器都没有,这个时候我们的发布通常是选择一个流量小的时候进行蛮力发布的,这个时候也许会对用户造成短暂的影响,但那个时候的我们是没有人力物力财力……去搞后面那些复杂的方式的。
而后来的某厂里有着充足的资源,我们有着多服务器群组,各种强大的发布工具……,通常我们是结合具体场景来选择合适的发布方式的。最常用的其中就是金丝雀发布和滚动发布。而在有些时候由于集群中的请求是随机分发的你并不能保证同一个用户的上一个请求和下一个请求还在同一个服务器上,这时如果旧的版本不能兼容新的版本的时候,如果是在业务流量低的时候,我们会考虑采用蓝绿部署的方式,如果在流量高峰期则会采用红黑发布的方式来避免服务器过载。
而针对一些特殊的功能也经常会采用滚动发布+功能功能开关的方式。新版本发上去之后,逐步打开开关验证。
总之,各种发布方式的本质目的都是为了提高我们的发布效率,保持系统可用性,减少对用户的影响能够让用户平滑的过渡到新的版本。