什么是灰度发布(金丝雀发布)
本文,我们来讨论一个企业里开发中的一个重要概念:灰度发布,及其解决方案。
基本概念
灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
理论与现实的思考冲突
之前的例子中,说的是从30-70的流量比例开始,慢慢调大新系统的接入流量比例,直到彻底完成新旧更替。
如果一切都很符合理想,没有什么外部约束的话,最好的方式一定是从0-100的比例开始,慢慢调整到100-0,是最安全最有稳定性的。
但现实总是有外部约束,例如:
1.来自效率的约束
产品经理:这个新功能三天内必须完全上线!
2.来自成本的约束
谁负责慢慢调节流量?谁来监控?或者交给算法来做,谁来写这个算法?涉及到的成本会很多。
那么如何权衡效率、成本与稳定性呢,就需要我们有充分的运维经验了。而这方面其实与开发是分不开的,我们开发者对于代码和业务复杂性的评估,将是我们去为灰度发布keep balance的重要依据。
在这里我们提出两个问题
“系统级”还是“接口级”?
那这样的话,是不是就意味着我们需要V1,V2,V3,V4四个版本?其中V2、3、4分别对A、B、C进行灰度。这样未免成本太高了。
思考一下,应该如何去做?
“接口级”还是“代码级”
如果刚才提到的C接口内部代码逻辑很复杂,但旧版本的C接口和新版本的C接口代码复用率很高。我们有必要开发出两种版本的C接口,然后再进行灰度吗?是不是可以只针对那一部分不一样的代码进行灰度呢?
如果想只针对一部分代码进行灰度,既然不再是针对接口了,那我们该如何把控流量呢?
停下来,再思考一下。在后面的解决方案中,我们再继续探讨。
实战解决方案
为了让我们能够热配置我们的灰度,那么这种配置就一定不能硬编码在我们的程序中。而且最好能以可读性较高、且较易编写的方式放在我们的配置文件/配置平台中。
毕竟我们现在想针对“代码级”的新旧版本进行灰度配置,那么可以想象,当需要灰度的代码块很多的时候,这种配置也会很多。如果不能以较好的格式存储,就会非常杂乱而不易维护。
那么应该如何设计这种配置的数据格式呢?比如可以像这样:
具体解释一下
serviceId 服务名
唯一标识我们需要灰度的代码块。因为不同的服务可能需要不同的灰度策略(比如当A服务希望现 在是70%灰度的时候,B服务希望目前只是30%的灰度),所以以服务id为唯一标识。
strategyType 灰度策略类型
在我们的示例中,只有PERCENT——按百分比进行灰度这种类型。但其实灰度策略可以有很多 种,比如黑名单策略,白名单策略……
percent 百分比
显然,这个percent字段是为了PERCENT策略类型服的。我们需要知道该服务想要的百分比值, 才能为它提供百分比灰度策略服务。
otherParam… 其他相关参数……
这个与percent参数类似,只是可能是为其他的灰度策略服务的。例如如果采取一个白名单策略, 也许我们就需要一个whitelist参数,看看有哪些用户可以纳入白名单。
那么这种数据结构,我们可以存在我们的数据库中,也可以写入我们的配置文件中,等等。
既然要针对“代码级”进行灰度,也就是应该会设计有如下逻辑:
//判断接下来是走旧流程还是走新流程
而isGray(this.serviceId) 方法应当抽象出来,专门设计到一个模块中,允许所有业务方进行调用。
isGray(this.serviceId)要做些什么呢?
获取到调用方的serviceId(通过方法传参获取到了)
根据serviceId,到配置文件/平台中获取相关数据,包括strategyType,percent等等
根据strategyType,并配合其他参数,执行相应的灰度逻辑。
返回true或false,告知业务方本次调用应当走入新旧哪个流程
每个业务方是否想要灰度,想要走什么灰度策略,都完全可以由自己来控制。而具体的策略逻辑,则由 我们的通用灰度模块来提供即可。
总 结
【自述】 大专毕业的爬虫工程师被裁,却拒绝了42K的Offer?
试用期没过,只因在公司上了1024?
五年级小学生自创编程语言,想到11岁时我干的“事儿”
一键三连「分享」、「点赞」和「在看」
技术干货与你天天见~