RPC多通道蓝绿发布实现原理
1. 概述
蓝绿发布可以让一组有依赖关系的应用并行发布、并行验证。但是,如果几组应用同时发布,却共用一套蓝绿流量比例,事情就有点麻烦了:这边还在小流量验证,那边已经准备全量引流,两边该听谁的?
直观的办法是把应用分成不同的【蓝绿通道】,各个通道自己控制摘流、引流和验证进度,互不干扰。但是,发布可以分组,请求链路却不一定跟着分组。同一个请求可能先经过通道1,再经过通道2,随后又回到通道1。这时只记一个“选蓝还是选绿”,就不够用了。
因此,多通道蓝绿发布需要解决两个问题: 每个通道可以独立控制流量比例,同一个请求在同一个通道内又要保持蓝绿选择一致。前者关系到发布能不能独立进行,后者关系到请求会不会在新老代码之间乱窜。本文就围绕这两个问题,梳理相关的实现思路,以及全局、局部通道配置叠加时遇到的问题。
2. 多通道目标与前提
2.1 目标
通过蓝绿通道划分,实现各通道不受干扰的并行发布、验证
各个蓝绿通道独立调整流量比例 (摘流、引流)
请求经过蓝绿通道内各个应用时选择的蓝、绿节点是一致的,要么都是蓝、要么都是绿 (流量在同一个蓝绿通道内不会蓝、绿乱窜)
2.2 前提
一半数量的服务器,可以承载整个集群的负载
一个应用只允许在一个蓝绿通道,不允许在多个蓝绿通道中同时关联同一个应用 (避免规则冲突)
业务同学在使用蓝绿通道时,应尽可能将链路上有改动依赖 (比如依赖下游新增的接口)的应用放到一个蓝绿通道
3. 通道内蓝绿流量比例控制
3.1 通道配置与下发
为实现局部蓝绿发布,首先我们需要全局下发(类似既有的流量事件SDK)蓝绿通道配置,蓝绿通道配置有如下要素:
| 通道要素 | 说明 |
|---|---|
| 蓝绿通道标识 | 每个蓝绿通道都有自己的标识,类似染色环境标识 |
| 蓝色流量比例 | 流量比例 |
| 应用名单 | 每个通道内包含的应用名单 |
通道配置的增删改都会广播下发到所有接入蓝绿发布能力的应用
流量事件SDK可通过遍历各通道的应用名单,比对当前应用名,判断【当前应用】是否需要关注本次变更事件,是否需要将事件下发到MQ、JOB、RPC。并得到当前应用现处的【蓝绿通道标识】
3.2 MQ、JOB:在当前应用控制流量
应用感知到上述事件后,需要按要求实现 MQ、JOB的迁移、避让,以实现摘流、引流 (既有逻辑,无需改动)。
MQ、JOB在做流量控制时, 落脚点是当前应用自身,通过下发的通道配置当前应用可以判断自己是否在蓝绿通道中,如果在蓝绿通道中,就按流量比例既定逻辑即可。
3.3 RPC:通过动态服务权重控制上游流量
RPC比较特殊,RPC的流量控制的 落脚点是当前应用上游,即当前应用收到蓝绿通道配置后,只能判断出自己身处蓝绿通道中,无法感知自己的所有上游 并通知上游节点按比例切流。
虽然当前应用无法感知、通知自己的上游切流,但是 上游应用都是通过注册中心发现当前应用节点的。
因此,当前应用通过下发的通道配置感知到自己在蓝绿通道中时,可按通道配置中的流量比例动态修改 自身在注册中心注册的实例的 权重。
为避免注册中心QPS尖刺,此处调用注册中心接口变更实例信息时,需打散请求削峰
注册中心上实例权重变更后, 当前应用上游会自动感知,后续调用时会按权重筛选节点,即实现了【RPC流量控制】
通过该思路,即可实现无需人工梳理完整的上游依赖即可实现蓝绿通道中应用RPC流量摘除、流量比例控制
4. 请求链路上的蓝绿决策
同一个请求在经过同一个蓝绿通道中的任意应用时,需要保持蓝、绿节点筛选决策结果一致,要么都选蓝节点,要么都选绿节点。
4.1 识别当前应用所属通道
各个应用可通过遍历上述全局广播下发的各通道的应用名单,比对自身应用名,得到当前应用现处的【蓝绿通道标识】
请回顾【前提】,每个应用只允许在一个蓝绿通道内。
4.2 识别下游应用所属通道
每个接入蓝绿发布能力的应用,在往注册中心注册服务实例时,需要将当前应用的 CMDB应用名作为服务实例元信息,写入到注册中心中。
当发生RPC调用时,如服务A调用服务B,服务A筛选节点时,通过注册中心元信息得知服务B的CMDB应用名。
然后通过流量事件SDK,搜索即可得到服务B (下游应用) 所在的蓝绿通道标识。
4.3 记录并透传各通道的决策
请求链路上,经过每一个蓝绿通道,都要按通道配置 (流量比例)做蓝绿节点筛选、决策, 并记录决策结果全链路透传
5. 通道决策图解
5.1 单通道场景:全局蓝绿开启时
图中服务A、B、C都属于通道1。请求进入通道时选择了绿色,后续调用继续沿用这个选择。
5.2 多通道场景:链路无交汇
当前场景,两个蓝绿通道各自按配置进行流量比例控制,互不影响。
5.3 多通道场景:链路有交汇
图中请求依次经过通道1、通道2、通道3,随后又回到前面的通道。如果链路上只保留一个蓝绿标识,前一个通道的选择就会干扰后一个通道。按通道分别记录第一次决策,并在再次进入该通道时沿用,才能保持各通道内的蓝绿选择一致。
6. 全局与局部通道的配置合并
请求链路上的通道决策明确后,还要处理配置侧的协同:一个应用同时受到全局和局部通道影响时,应该采用哪份配置,又该怎样衔接发布事件?
6.1 配置生效优先级
按使用需求,一个应用最多只能同时处于1个正在发布中蓝绿通道,但是可能会受两个通道事件影响。
局部蓝绿通道(通道配置中的应用名单指定)
全局蓝绿通道 (全局蓝绿通道开启时,默认所有应用都会归属全局通道)
虽然一个应用可能会受到两个通道流量事件影响,但是一个应用只能在一个通道中进行发布
在上述背景下,可得到如下 通道配置生效状态矩阵:
| 全局通道开启 | 全局通道关闭 | |
|---|---|---|
| 局部通道开启 | 局部通道配置生效 应用服从局部通道流量比例 | 局部通道配置生效 应用服从局部通道流量比例 |
| 局部通道关闭 | 全局通道配置生效 | 都不生效 |
6.2 配置变更事件流
确定配置优先级后,还需要看配置变更事件。当全局通道和局部通道同时开启时,通道内应用会同时受两个通道变更事件流影响。
6.2.1 事件序列
现假设两个通道事件流分别按如下顺序发生:
全局通道:开始发布、蓝色比例0、蓝色比例30、蓝色比例50、蓝色比例100、蓝色比例80、蓝色比例50、完成发布
局部通道:开始发布、蓝色比例0、蓝色比例20、蓝色比例70、蓝色比例100、蓝色比例70、蓝色比例30、完成发布
6.2.2 事件重叠
上述两组事件序列,同时作用在一个应用时,根据事件序列发生的先后关系,会产生如下典型结果:
以MQ为例,讨论事件重叠对应用状态的影响
黄色高亮列为实际生效的、会被应用感知的通道配置变更
时间12、13、14这段时间内,应用绿色集群应该完成MQ摘流,但是在事件重叠的场景下,不符合预期
会连续收到两次【开始发布】事件,不符合【开始发布-比例变更-完成发布】的事件顺序预期
会连续收到两次【完成发布】事件,不符合【开始发布-比例变更-完成发布】的事件顺序预期
6.2.3 补偿与重放
在局部蓝绿通道【完成发布】时,检查全局蓝绿通道是否还在发布中。
如果全局蓝绿通道还在发布中,则补偿一个【开始发布】事件,同时重发全局蓝绿通道配置(最近一个流量比例值)。
如下所示:
通过以上补偿+重放的方式,可以将应用状态回归到服从全局通道配置的状态。
7. 总结
多通道蓝绿发布,一方面要让各组应用独立控制发布进度,另一方面又要让跨通道的请求保持各自的蓝绿决策。通过动态服务权重控制流量,再按通道记录、透传请求的决策结果,就把这两件事串了起来。
全局通道和局部通道叠加后,还需要处理配置优先级与事件顺序。配置选对了,事件也要接得上;全局通道仍在发布时,局部通道结束后的补偿和重放,就是为了让应用重新回到全局通道的发布状态。




