一、为什么需要具备灰度发布能力?
随着微服务架构的普及,服务数量激增,版本更新频繁,如果缺少灰度的能力,容易对现有的生产运行业务造成影响,并且新上线的系统和功能也需要灰度的能力来验证可行性和效果,简而言之,无论是对于系统运行稳定安全还是对于验证业务效果,灰度发布/验证的能力都是现代软件架构所必须的。
二、现代应用发布有哪些模式?
- 蓝绿发布
- 定义
蓝绿发布,是在生产环境稳定集群之外,额外部署一个与稳定集群规模相同的新集群,并通过流量控制,逐步引入流量至新集群直至100%,原先稳定集群将与新集群同时保持在线一段时间,期间发生任何异常,可立刻将所有流量切回至原稳定集群,实现快速回滚。直到全部验证成功后,下线旧集群,流量全部切换到新的集群。 - 优点
老版本应用不需要停机,可以实现快速回退。 - 缺点
需要两倍的机器资源用于部署相同规模的集群。
- 滚动发布
- 定义
取出应用集群中的一个或者多个应用实例停止服务并进行新版本的更新,然后将新版本投入使用,通过逐个替换实例来逐步部署新版本的应用,直到所有实例都被替换完成为止。例如第一批次10%的实例更新版本,第二批次30%的实例更新版本,最后一批次60%的实例更新版本。一般来说前面的批次需要比较长的验证时间,在验证通过风险降低以后逐步放大更新的比例。滚动发布期间,新旧版本共存。 - 优点
用户体验平滑、自动化程度高,无需额外的资源投入。 - 缺点
由于滚动更新的过程一般分成多个批次,需要等待验证的时间间隔较长,发布和回退的时间比较长;按照批次更新,需要平滑的流量过度机制,发布工具复杂。
- 灰度发布
- 定义
灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。与蓝绿发布有明显区别的是蓝绿发布需要两倍的机器资源,其主要目的在于安全的发布应用,而灰度发布的目的在于小流量的测试来获得一定的验证结论。
金丝雀发布名称的由来:17世纪,英国矿井工人发现金丝雀对于瓦斯十分敏感,于是下井时都会带上一只金丝雀作为瓦斯危险程度的提示指标。
一般情况下,灰度发布是额外部署一个金丝雀的服务实例为新版本,如果验证金丝雀实例验证通过,则一次性更新其他的版本,发布期间新旧版本共存。 - 优点
部署新的金丝雀版本进行验证,对于用户体验影响较小,只影响灰度部分的用户流量,资源的损耗比较小。 - 缺点
占用少量的资源。
三、前端应用的灰度发布
- 使用nginx upstram或者split_clients使用nginx upstram模块或者或者split_clients模块实现前端应用按照一定的比例进行分流,从而实现灰度,具体可以参考文章:《使用nginx split_clients实现AB测试》。
- 优点
路由配置简单,不引入新的组件。 - 缺点
配置不够灵活,逐步调整灰度的比例时需要人工介入,分流和发布流程割裂。
- 开源组件ABTestingGatewayABTestingGateway 是一个可以动态设置分流策略的灰度发布系统,工作在7层负载,基于nginx和ngx-lua 开发,使用 redis 作为分流策略数据库,可以实现动态分流调度功能。
- 优点:
- 支持多种分流方式,目前包括iprange、uidrange、uid尾数和指定uid分流
- 动态设置分流策略,即时生效,无需重启
- 可扩展性,提供了开发框架,开发者可以灵活添加新的分流方式,实现二次开发
- 高性能,压测数据接近原生nginx转发
- 灰度系统配置写在nginx配置文件中,有页面可以方便管理员配置
- 适用于多种场景:灰度发布、AB测试和负载均衡等
- 缺点:
- 引入了新的组件,包括nginx-lua和redis,架构变得复杂,维护起来比较困难。
- 分流和发布流程割裂。
- 由服务端进行灰度决策返回前端资源灰度策略保存在服务后端,每次请求发往后端,由后端应用根据策略决策返回不同版本的对应的前端资源,这种方式需要独立开发后端的策略配置服务,并且前后端耦合比较高。
- 优点
可以比较灵活的配置,可以配置多版本并行。 - 缺点
- 不适用于前后端分离的应用
- 分流和发布流程割裂。
四、后端应用的灰度发布
- 使用nginx upstram或者split_clients
同前端应用分流类似,可以使用nginx的负载均衡或者客户端分流模块进行分流。 - 使用API网关实现灰度
可以在API网关编写filter,在filter中根据一定的策略进行分流转发,例如根据用户id、根据请求头参数、url参数等,在spring cloud体系中一般是基于ribbon进行转发。 - Spring Cloud Gray组件
Spring Cloud Gray 是一套开源的微服务灰度路由解决方案,是面向于spring cloud体系架构的,它抽象出了spring-cloud-gray-webui提供策略配置页面,spring-cloud-gray-server负责灰度决策、灰度追踪等信息的管理以及持久化,spring-cloud-gray-client定义了一套灰度路由决策模型,灰度信息追踪模型,以及和spring-cloud-gray-server的基本通信功能。
spring cloud gray组件既可以支持灰度发布,还可以支持蓝绿发布。
整体架构如上所示,webui提供策略配置,client端从admin获取灰度策略,从注册中心获取到所有的服务实例,根据灰度策略进行灰度分流。
spring cloud gray类似的方案整体比较完善,有对应的平台可以进行方便的操作,也支持比较细力度的灰度流程,需要比较关注的是引入了一整套的灰度发布的平台,需要多出额外的维护成本,并且一般情况下公司内部都会有自己的发布系统,比较难直接引入在发布流程中使用,这也是上面一直提到的发布和灰度流程割裂的情况,从组件不耦合的角度来看,灰度组件独立是很好的,但也有不少的公司是希望能够结合发布系统在统一的流程管理里面去实现灰度的发布和验证,这也是比较好理解的。针对这种情况建议有条件的可以根据spring cloud gray的实现方案进行内部开发。
五、预发布/沙箱灰度发布
以上的各类方案都是针对前端、后端应用的单独灰度发布方案,在底层数据库结构变更等场景下也不适用,无法实现全流程的灰度,在有条件的情况下,建议搭建独立预发布/沙箱环境,从前端入口、静态资源、后端应用、数据库等全面部署一整套全新的环境,此环境数据库可以通过一些数据库迁移工具如canal等进行数据迁移同步,保证底层数据的一致性,从而可以进行比较全面的灰度发布验证。