1.灰度发布
灰度发布,是在生产环境稳定集群之外,额外部署一个小规模的灰度集群,并通过流量控制,引入部分流量到灰度集群,进行生产全量发布前的灰度验证。如果验证失败,可立刻将所有流量切回至稳定集群,取消灰度发布过程;如果验证成功,则将新版本进行全量发布升级至生产环境稳定集群,完成灰度发布过程。
灰度发布也叫金丝雀发布
金丝雀发布一般先发 1 台,或者一个小比例,例如 2% 的服务器,主要做流量验证用,也称为金丝雀 (Canary) 测试(国内常称灰度测试)。以前旷工开矿下矿洞前,先会放一只金丝雀进去探是否有有毒气体,看金丝雀能否活下来,金丝雀发布由此得名。简单的金丝雀测试一般通过手工测试验证,复杂的金丝雀测试需要比较完善的监控基础设施配合,通过监控指标反馈,观察金丝雀的健康状况,作为后续发布或回退的依据。
2.蓝绿发布
2.1 什么是蓝绿发布
蓝绿发布,是在生产环境稳定集群之外,额外部署一个与稳定集群规模相同的新集群,并通过流量控制,逐步引入流量至新集群直至 100%,原先稳定集群将与新集群同时保持在线一段时间,期间发生任何异常,可立刻将所有流量切回至原稳定集群,实现快速回滚。直到全部验证成功后,下线老的稳定集群,新集群成为新的稳定集群。
2.2 发布流程
- 新集群部署, 老集群称为蓝组,新集群称为绿组
- 流量切换到新集群
- 服务验证
- 如果有问题,流量切回老集群
- 观察一段时间后,回收老集群
2.3 为什么需要蓝绿发布
有了灰度发布,为什么还需要蓝绿发布呢 ?
- 服务全量发布后,发现故障回滚比较慢
- 灰度集群容量有限,真实流量可能超过集群服务能力,可能导致灰度集群过载
- 灰度环境发现的问题有限。比如数据库问题、性能问题,毕竟才少量的请求
- 灰度发布后仍然需要全量发布,也会发生一些意外情况导致发布失败
蓝绿发布可以解决以上灰度发布存在的问题
- 如果发生故障,流浪可以迅速切换到原来的稳定集群
- 新的集群承载所有流量,不会担心压力问题
- 同上,新的集群承载所有流量,可以验证各种场景
- 新集群已经发布完成,运行一段时间没有问题后不需要重新发布,把原来的稳定集群撤掉就可以了
但是,也不能完全使用蓝绿发布代替灰度发布,蓝绿发布成本很高,灰度发布只需要一点资源就可以验证大部分问题。
3. 滚动发布
3.1 什么是滚动发布
在灰度发布的基础上更近一步,实现流量的平滑切换,发布时先将老版本的流量从LB上摘除,然后清除老版本,发布新版本,再将流量切到新版本上。
3.2 发布流程
一次滚动式发布一般由若干个发布批次组成,每批的数量一般是可以配置的(可以通过发布模板定义)。例如第一批 1 台(金丝雀),第二批 10%,第三批 50%,第四批 100%。每个批次之间留观察间隔,通过手工验证或监控反馈确保没有问题再发下一批次,所以总体上滚动式发布过程是比较缓慢的 (其中金丝雀的时间一般会比后续批次更长,比如金丝雀 10 分钟,后续间隔 2 分钟)。
滚动式发布国外术语通常叫 Rolling Update Deployment。
4. 其他发布模式
4.1 功能开关发布
利用代码中的功能开关(Feature Flag/Toggle/Switch)来控制发布逻辑,一般不需要复杂的发布工具和智能 LB 配合,是一种相对比较低成本和简单的发布方式。这种方式也是支持现代 DevOps 理念,研发人员可以灵活定制和自助完成的发布方式。
实践要点
- 一般需要配置中心支持
- 应用上线后,一般开关先不开,有运维或者研发人员通知开关中心打开开关,验证通过后则不发完成。验证失败则关闭开关,切回老的逻辑
4.2 A/B Test
原来主要用于产品功能的比对测试,收集用户反馈和对比数据做产品功能设计的决策。实际上,A/B 测试也可以作为一种新功能发布技术。
主要目的:
- 判断哪个更好
- 计算收益
对于一般的 ABTest 实验,其实本质上就是把平台的流量均匀分为几个组,每个组添加不同的策略,然后根据这几个组的用户数据指标,例如:留存、人均观看时长、基础互动率等等核心指标,最终选择一个最好的组上线。
基于 LB 方式实现 A/B 测试,LB 需要能够通过某种条件做流量路由,例如通过 client ip,设备类型,浏览器类型,甚至是定制的 HTTP Header 或查询字符串。
4.3 影子测试
对于一些涉及核心业务的遗留系统的升级改造,为了确保万无一失,有一种称为影子测试的大招,采用比较复杂的流量复制、回放和比对技术实现。
如上图所示,测试开始前,需要在测试环境部署一份 legacy 服务和 experimental 服务,同时将生产数据库复制两份到测试环境。同时需要将生产请求日志收集起来,一般可以通过 kafka 队列收集,然后通过类似 goreplay 附录 6.8 这样的工具,消费 kafka 里头的请求日志,复制回放,将请求分发到 legacy 服务和 experimental 服务,收到响应后进行比对,如果所有响应比对成功,则可以认为 legacy 服务和 experimental 服务在功能逻辑上是等价的;如果有响应比对失败,则认为两者在功能逻辑上不等价,需要修复 experimental 并重新进行影子测试,直到全部比对成功。根据系统复杂度和关键性不同,比对测试时间短的可能需要几周,长的可达半年之久。
影子测试一般适用于遗留系统的等价重构迁移,例如. net 转 Java,或者 SQLServer 数据库升级为 MySQL 数据库,且外部依赖不能太多,否则需要开发很多 mock,测试部署成本会很高,且比对测试更加复杂和不稳定。
当当网有一个比较成功的交易系统. NET 转 Java 迁移项目,采用了影子测试技术,值得参考借鉴。
影子测试门槛比较高,一般用于核心系统重构验证。
5. 总结
- 滚动发布一般配合灰度发布(金丝雀发布),先通过少量流量进行服务验证,再按批次增量发布,并且能够保证零停机,用户体验比较好。
- 对于涉及关键核心业务的新功能上线,采用 A/B 测试,可以显著降低发布风险,A/B 测试是唯一一种支持针对特定用户组进行生产测试的高级发布技术。当然 A/B 测试的投入不低。
- 对于关键核心业务的迁移重构,为确保万无一失,最后的一个大招是影子测试,影子测试对生产流量和用户完全无影响。当然这个大招的投入成本和门槛都高。
- 上述的各种发布策略并不是非此即彼的,一个公司常常会综合采用多种发布技术作为互补,实现灵活的发布能力。例如主流的发布手段是金丝雀 + 滚动式发布,某些业务线可能根据业务场景需要采用功能开关发布,还有一些业务线则可能采用高级的 A/B 测试发布手段。