1:概念

灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行 A/B testing,即让一部分用户继续用产品特性 A,一部分用户开始用产品特性 B,如果用户对 B 没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到 B 上面来。
灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

2:引言

在 V1 版本的产品和 V2 版本的产品之间,进行灰度是十分合理的。但有时候并非只是这么
简单,例如:
V1 和 V2 之间有 A、B、C 三个新功能接口的迭代。其中 A 功能比较简单,也不是核心功能,
基本不太需要灰度就可以发布;而 C 功能是非常核心且复杂的重点功能,
一旦出 bug 可能导致严重的线上问题,需要谨慎发布。
那么如果我们只针对 V1 和 V2 进行灰度,就会发现整个版本迭代的效率是以 A、B、C 三个
功能中最慢的那个为准的。我们是否有可能针对 A、B、C 分别进行灰度呢?这样就可以迅速
上线 A 这样比较简单的新功能,而对于复杂的 C 功能则延缓彻底上线的速度。
那这样的话,是不是就意味着我们需要 V1,V2,V3,V4 四个版本?其中 V2、3、4 分别对
A、B、C 进行灰度。这样未免成本太高了。
        该如何控制其发布颗粒度呢?

3:总体原则

控制权交由业务,实现粒度自由。首先确定范围:系统级、接口级、代码级

4:详细拆解

如果刚才提到的C接口内部代码逻辑很复杂,但旧版本的 C 接口和新版本的 C 接口代码复
用率很高。我们有必要开发出两种版本的C接口,然后再进行灰度吗?是不是可以只针对那
一部分不一样的代码进行灰度呢?
如果想只针对一部分代码进行灰度,既然不再是针对接口了,那我们该如何把控流量呢?

既然要针对“代码级”
进行灰度,也就是应该会设计有如下逻辑:

1:代码形式

//判断接下来是走旧流程还是走新流程
 boolean gray = isGray ( this.serviceId );
 //如果判断为 false,走旧流程
 if ( gray == false ) {
 //doSomething
 ...
 }
 //如果判断为 true,走新流程
 if ( gray == true ) {
 //doSomething
 ...
 }


而 isGray(this.serviceId) 方法应当抽象出来,专门设计到一个模块中,允许所有业务方进行调用。
isGray(this.serviceId)要做些什么呢?

2:步骤

1.获取到调用方的 serviceId(通过方法传参获取到了)
2.根据 serviceId,到配置文件/平台中获取相关数据,包括 strategyType,percent 等等
3.根据 strategyType,并配合其他参数,执行相应的灰度逻辑。
4.返回 true 或 false,告知业务方本次调用应当走入新旧哪个流程
也就是说,我们可以自设计一个通用灰度模块,在里面实现 isGray 方法。
而具体的调用,则交给业务方。

3:小结

每个业务方是否想要灰度,想要走什么灰度策略,都完全可以由自己来控制。而具体的策略
逻辑,则由 我们的通用灰度模块来提供即可。