文章

RPC多通道蓝绿发布实现原理

RPC多通道蓝绿发布实现原理

1. 概述

蓝绿发布可以让一组有依赖关系的应用并行发布、并行验证。但是,如果几组应用同时发布,却共用一套蓝绿流量比例,事情就有点麻烦了:这边还在小流量验证,那边已经准备全量引流,两边该听谁的?

直观的办法是把应用分成不同的【蓝绿通道】,各个通道自己控制摘流、引流和验证进度,互不干扰。但是,发布可以分组,请求链路却不一定跟着分组。同一个请求可能先经过通道1,再经过通道2,随后又回到通道1。这时只记一个“选蓝还是选绿”,就不够用了。

因此,多通道蓝绿发布需要解决两个问题: 每个通道可以独立控制流量比例,同一个请求在同一个通道内又要保持蓝绿选择一致。前者关系到发布能不能独立进行,后者关系到请求会不会在新老代码之间乱窜。本文就围绕这两个问题,梳理相关的实现思路,以及全局、局部通道配置叠加时遇到的问题。

2. 多通道目标与前提

2.1 目标

  1. 通过蓝绿通道划分,实现各通道不受干扰的并行发布、验证

  2. 各个蓝绿通道独立调整流量比例 (摘流、引流)

  3. 请求经过蓝绿通道内各个应用时选择的蓝、绿节点是一致的,要么都是蓝、要么都是绿 (流量在同一个蓝绿通道内不会蓝、绿乱窜)

2.2 前提

  1. 一半数量的服务器,可以承载整个集群的负载

  2. 一个应用只允许在一个蓝绿通道,不允许在多个蓝绿通道中同时关联同一个应用 (避免规则冲突)

  3. 业务同学在使用蓝绿通道时,应尽可能将链路上有改动依赖 (比如依赖下游新增的接口)的应用放到一个蓝绿通道

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 并沿用绿色决策

图中服务A、B、C都属于通道1。请求进入通道时选择了绿色,后续调用继续沿用这个选择。

5.2 多通道场景:链路无交汇

链路无交汇:通道 1 走绿色、通道 2 走蓝色,按各自比例控制

当前场景,两个蓝绿通道各自按配置进行流量比例控制,互不影响。

5.3 多通道场景:链路有交汇

链路有交汇:请求依次跨通道 1、2、3 并记录首次决策

图中请求依次经过通道1、通道2、通道3,随后又回到前面的通道。如果链路上只保留一个蓝绿标识,前一个通道的选择就会干扰后一个通道。按通道分别记录第一次决策,并在再次进入该通道时沿用,才能保持各通道内的蓝绿选择一致。

6. 全局与局部通道的配置合并

请求链路上的通道决策明确后,还要处理配置侧的协同:一个应用同时受到全局和局部通道影响时,应该采用哪份配置,又该怎样衔接发布事件?

6.1 配置生效优先级

按使用需求,一个应用最多只能同时处于1个正在发布中蓝绿通道,但是可能会受两个通道事件影响。

  1. 局部蓝绿通道(通道配置中的应用名单指定)

  2. 全局蓝绿通道 (全局蓝绿通道开启时,默认所有应用都会归属全局通道)

虽然一个应用可能会受到两个通道流量事件影响,但是一个应用只能在一个通道中进行发布

在上述背景下,可得到如下 通道配置生效状态矩阵:

 全局通道开启全局通道关闭
局部通道开启局部通道配置生效
应用服从局部通道流量比例
局部通道配置生效
应用服从局部通道流量比例
局部通道关闭全局通道配置生效都不生效

6.2 配置变更事件流

确定配置优先级后,还需要看配置变更事件。当全局通道和局部通道同时开启时,通道内应用会同时受两个通道变更事件流影响。

6.2.1 事件序列

现假设两个通道事件流分别按如下顺序发生:

  1. 全局通道:开始发布、蓝色比例0、蓝色比例30、蓝色比例50、蓝色比例100、蓝色比例80、蓝色比例50、完成发布

  2. 局部通道:开始发布、蓝色比例0、蓝色比例20、蓝色比例70、蓝色比例100、蓝色比例70、蓝色比例30、完成发布

6.2.2 事件重叠

上述两组事件序列,同时作用在一个应用时,根据事件序列发生的先后关系,会产生如下典型结果:

以MQ为例,讨论事件重叠对应用状态的影响

黄色高亮列为实际生效的、会被应用感知的通道配置变更

事件重叠的状态表:时间 12 到 14 绿色集群仍在消费 MQ

  1. 时间12、13、14这段时间内,应用绿色集群应该完成MQ摘流,但是在事件重叠的场景下,不符合预期

  2. 会连续收到两次【开始发布】事件,不符合【开始发布-比例变更-完成发布】的事件顺序预期

  3. 会连续收到两次【完成发布】事件,不符合【开始发布-比例变更-完成发布】的事件顺序预期

6.2.3 补偿与重放

在局部蓝绿通道【完成发布】时,检查全局蓝绿通道是否还在发布中。

如果全局蓝绿通道还在发布中,则补偿一个【开始发布】事件,同时重发全局蓝绿通道配置(最近一个流量比例值)。

如下所示:

补偿与重放后的状态表:时间 11 补偿开始发布并重放 100

通过以上补偿+重放的方式,可以将应用状态回归到服从全局通道配置的状态。

7. 总结

多通道蓝绿发布,一方面要让各组应用独立控制发布进度,另一方面又要让跨通道的请求保持各自的蓝绿决策。通过动态服务权重控制流量,再按通道记录、透传请求的决策结果,就把这两件事串了起来。

全局通道和局部通道叠加后,还需要处理配置优先级与事件顺序。配置选对了,事件也要接得上;全局通道仍在发布时,局部通道结束后的补偿和重放,就是为了让应用重新回到全局通道的发布状态。

本文由作者按照 CC BY 4.0 进行授权