什么是灰度發(fā)布(金絲雀發(fā)布)

本文,我們來(lái)討論一個(gè)企業(yè)里開(kāi)發(fā)中的一個(gè)重要概念:灰度發(fā)布,及其解決方案。
基本概念
灰度發(fā)布(又名金絲雀發(fā)布)是指在黑與白之間,能夠平滑過(guò)渡的一種發(fā)布方式。在其上可以進(jìn)行A/B testing,即讓一部分用戶(hù)繼續(xù)用產(chǎn)品特性A,一部分用戶(hù)開(kāi)始用產(chǎn)品特性B,如果用戶(hù)對(duì)B沒(méi)有什么反對(duì)意見(jiàn),那么逐步擴(kuò)大范圍,把所有用戶(hù)都遷移到B上面來(lái)?;叶劝l(fā)布可以保證整體系統(tǒng)的穩(wěn)定,在初始灰度的時(shí)候就可以發(fā)現(xiàn)、調(diào)整問(wèn)題,以保證其影響度。

理論與現(xiàn)實(shí)的思考沖突
之前的例子中,說(shuō)的是從30-70的流量比例開(kāi)始,慢慢調(diào)大新系統(tǒng)的接入流量比例,直到徹底完成新舊更替。
如果一切都很符合理想,沒(méi)有什么外部約束的話(huà),最好的方式一定是從0-100的比例開(kāi)始,慢慢調(diào)整到100-0,是最安全最有穩(wěn)定性的。
但現(xiàn)實(shí)總是有外部約束,例如:
1.來(lái)自效率的約束
產(chǎn)品經(jīng)理:這個(gè)新功能三天內(nèi)必須完全上線(xiàn)!
2.來(lái)自成本的約束
誰(shuí)負(fù)責(zé)慢慢調(diào)節(jié)流量?誰(shuí)來(lái)監(jiān)控?或者交給算法來(lái)做,誰(shuí)來(lái)寫(xiě)這個(gè)算法?涉及到的成本會(huì)很多。
那么如何權(quán)衡效率、成本與穩(wěn)定性呢,就需要我們有充分的運(yùn)維經(jīng)驗(yàn)了。而這方面其實(shí)與開(kāi)發(fā)是分不開(kāi)的,我們開(kāi)發(fā)者對(duì)于代碼和業(yè)務(wù)復(fù)雜性的評(píng)估,將是我們?nèi)榛叶劝l(fā)布keep balance的重要依據(jù)。
在這里我們提出兩個(gè)問(wèn)題
“系統(tǒng)級(jí)”還是“接口級(jí)”?
那這樣的話(huà),是不是就意味著我們需要V1,V2,V3,V4四個(gè)版本?其中V2、3、4分別對(duì)A、B、C進(jìn)行灰度。這樣未免成本太高了。
思考一下,應(yīng)該如何去做?
“接口級(jí)”還是“代碼級(jí)”
如果剛才提到的C接口內(nèi)部代碼邏輯很復(fù)雜,但舊版本的C接口和新版本的C接口代碼復(fù)用率很高。我們有必要開(kāi)發(fā)出兩種版本的C接口,然后再進(jìn)行灰度嗎?是不是可以只針對(duì)那一部分不一樣的代碼進(jìn)行灰度呢?
如果想只針對(duì)一部分代碼進(jìn)行灰度,既然不再是針對(duì)接口了,那我們?cè)撊绾伟芽亓髁磕兀?/span>
停下來(lái),再思考一下。在后面的解決方案中,我們?cè)倮^續(xù)探討。
實(shí)戰(zhàn)解決方案
為了讓我們能夠熱配置我們的灰度,那么這種配置就一定不能硬編碼在我們的程序中。而且最好能以可讀性較高、且較易編寫(xiě)的方式放在我們的配置文件/配置平臺(tái)中。
畢竟我們現(xiàn)在想針對(duì)“代碼級(jí)”的新舊版本進(jìn)行灰度配置,那么可以想象,當(dāng)需要灰度的代碼塊很多的時(shí)候,這種配置也會(huì)很多。如果不能以較好的格式存儲(chǔ),就會(huì)非常雜亂而不易維護(hù)。
那么應(yīng)該如何設(shè)計(jì)這種配置的數(shù)據(jù)格式呢?比如可以像這樣:

具體解釋一下
serviceId 服務(wù)名
唯一標(biāo)識(shí)我們需要灰度的代碼塊。因?yàn)椴煌姆?wù)可能需要不同的灰度策略(比如當(dāng)A服務(wù)希望現(xiàn) 在是70%灰度的時(shí)候,B服務(wù)希望目前只是30%的灰度),所以以服務(wù)id為唯一標(biāo)識(shí)。
strategyType 灰度策略類(lèi)型
在我們的示例中,只有PERCENT——按百分比進(jìn)行灰度這種類(lèi)型。但其實(shí)灰度策略可以有很多 種,比如黑名單策略,白名單策略……
percent 百分比
顯然,這個(gè)percent字段是為了PERCENT策略類(lèi)型服的。我們需要知道該服務(wù)想要的百分比值, 才能為它提供百分比灰度策略服務(wù)。
otherParam… 其他相關(guān)參數(shù)……
這個(gè)與percent參數(shù)類(lèi)似,只是可能是為其他的灰度策略服務(wù)的。例如如果采取一個(gè)白名單策略, 也許我們就需要一個(gè)whitelist參數(shù),看看有哪些用戶(hù)可以納入白名單。
那么這種數(shù)據(jù)結(jié)構(gòu),我們可以存在我們的數(shù)據(jù)庫(kù)中,也可以寫(xiě)入我們的配置文件中,等等。
既然要針對(duì)“代碼級(jí)”進(jìn)行灰度,也就是應(yīng)該會(huì)設(shè)計(jì)有如下邏輯:
//判斷接下來(lái)是走舊流程還是走新流程
而isGray(this.serviceId) 方法應(yīng)當(dāng)抽象出來(lái),專(zhuān)門(mén)設(shè)計(jì)到一個(gè)模塊中,允許所有業(yè)務(wù)方進(jìn)行調(diào)用。
isGray(this.serviceId)要做些什么呢?
獲取到調(diào)用方的serviceId(通過(guò)方法傳參獲取到了)
根據(jù)serviceId,到配置文件/平臺(tái)中獲取相關(guān)數(shù)據(jù),包括strategyType,percent等等
根據(jù)strategyType,并配合其他參數(shù),執(zhí)行相應(yīng)的灰度邏輯。
返回true或false,告知業(yè)務(wù)方本次調(diào)用應(yīng)當(dāng)走入新舊哪個(gè)流程
每個(gè)業(yè)務(wù)方是否想要灰度,想要走什么灰度策略,都完全可以由自己來(lái)控制。而具體的策略邏輯,則由 我們的通用灰度模塊來(lái)提供即可。


總 結(jié)



【自述】 大專(zhuān)畢業(yè)的爬蟲(chóng)工程師被裁,卻拒絕了42K的Offer?

試用期沒(méi)過(guò),只因在公司上了1024?

五年級(jí)小學(xué)生自創(chuàng)編程語(yǔ)言,想到11歲時(shí)我干的“事兒”
一鍵三連「分享」、「點(diǎn)贊」和「在看」
技術(shù)干貨與你天天見(jiàn)~

