金絲雀(灰度)發(fā)版系列一,基于Kong實(shí)現(xiàn)

金絲雀發(fā)布(Canary Releases)介紹

為什么叫金絲雀發(fā)布

以前,英國(guó)的煤礦工人在下礦井之前,為防止自己中毒,會(huì)帶著一只金絲雀,金絲雀對(duì)瓦斯非常敏感,如果發(fā)現(xiàn)金絲雀有異樣,說(shuō)明礦井中的瓦斯?jié)舛冗^(guò)大,有中毒的危險(xiǎn),從而給工人提到一個(gè)預(yù)警的作用。所以后來(lái)也將灰度發(fā)布叫做金絲雀發(fā)布


canary.png

灰度發(fā)布作用

  • 傳統(tǒng)軟件公司的新版本發(fā)布間隔一般比較長(zhǎng),幾個(gè)月、半年甚至于一年等情況都有,每次新版本的功能點(diǎn)較多,發(fā)布異常謹(jǐn)慎,新版本發(fā)布帶來(lái)的動(dòng)靜非常的大,我曾經(jīng)面試過(guò)一個(gè)傳統(tǒng)軟件行業(yè)的同學(xué),之所以離職就是因?yàn)樗诠久看伟l(fā)版都放到半夜,所有的研發(fā)都盯著系統(tǒng),防止新版本發(fā)布引起生產(chǎn)事故,這個(gè)同學(xué)就是因?yàn)殚L(zhǎng)期半夜加班,身體吃不消才離職

  • 互聯(lián)網(wǎng)行業(yè)的公司,節(jié)奏比傳統(tǒng)軟件公司快很多,一般大的迭代版本最長(zhǎng)一個(gè)月,絕大部分都是半個(gè)月一次新版本,作者所在公司就是半個(gè)月一個(gè)迭代,最初的時(shí)候由于軟件質(zhì)量、系統(tǒng)架構(gòu)穩(wěn)定等原因,導(dǎo)致新版本發(fā)布引起的生產(chǎn)事故比例非常的高,幾乎到了每次發(fā)版都要出事故的節(jié)奏,讓研發(fā)同學(xué)苦不堪言。

  • 對(duì)于互聯(lián)網(wǎng)公司來(lái)說(shuō)小的bugfix,或者小的迭代的頻率就更高了,比如作者公司200多個(gè)線上服務(wù),每天都會(huì)有生產(chǎn)環(huán)境服務(wù)更新,對(duì)于大的互聯(lián)網(wǎng)公司,比如BAT、Google、Facebook每天都有幾萬(wàn)個(gè)生產(chǎn)環(huán)境服務(wù)更新,這么高的頻率帶來(lái)的生產(chǎn)事故也會(huì)隨之升高

  • 如何降低由于版本發(fā)布帶來(lái)的事故呢?code review增加代碼質(zhì)量、提高測(cè)試的覆蓋面和作用、增加仿真環(huán)境提前發(fā)現(xiàn)bug、灰度發(fā)布

  • 灰度發(fā)布作用就是新版本發(fā)布只會(huì)接入部分流量或者只對(duì)小部分用戶開(kāi)放,這樣即使有影響也只會(huì)影響到小部分用戶,將損失降到最低。

灰度發(fā)布策略

架構(gòu)設(shè)計(jì)

灰度的設(shè)計(jì)可以從Server端和Client端來(lái)考慮,兩端相輔相成,又相互隔離,獨(dú)立實(shí)現(xiàn),對(duì)于純Web的公司來(lái)說(shuō)就不用考慮Client端的灰度,對(duì)于有APP的公司來(lái)說(shuō),可以根據(jù)APP的重要程度來(lái)判斷是否需要進(jìn)行Client的灰度。

  • Client灰度

    Client的灰度不是本文的主要內(nèi)容,只會(huì)做簡(jiǎn)要的介紹,Client的灰度依賴(lài)于對(duì)Client端的升級(jí)控制,升級(jí)接口需要有足夠的控制能力,能夠支持特定用戶的升級(jí)策略,同時(shí)由于Client的更新升級(jí)比較慢,所以出現(xiàn)了Hot Patch熱更新,但是由于iPhone系統(tǒng)的限制,很多功能也無(wú)法滿足。還有一種辦法就是代碼冗余,客戶端會(huì)同時(shí)冗余兩個(gè)版本的代碼,然后根據(jù)服務(wù)端的控制指令,來(lái)切換運(yùn)行,這種方式導(dǎo)致代碼比較冗余笨重,不太建議使用,很早之前滴滴使用過(guò)這種辦法進(jìn)行客戶端灰度。


    客戶端灰度.png
  • Server灰度

    服務(wù)端的灰度方案一般都是基于網(wǎng)關(guān)來(lái)實(shí)現(xiàn),比如本文將的Kong、或者Spring Cloud的zuul(下一章講解),網(wǎng)關(guān)根據(jù)特定的策略將流量調(diào)度到不同的后端業(yè)務(wù)服務(wù)上,如果有異常則踢出或者回滾新的業(yè)務(wù)系統(tǒng),如果正常則增大發(fā)布比例


    服務(wù)端灰度.png

灰度實(shí)現(xiàn)策略

灰度發(fā)版的策略一般包含下邊幾種

  • 流量隨機(jī)比例

    流量隨機(jī)比例的灰度策略,就是根據(jù)用戶的流量指定一個(gè)比例,隨機(jī)的將流量根據(jù)比例調(diào)度到新服務(wù),比例一般都是由低到高,比如5%-20%,比例可以根據(jù)自己的業(yè)務(wù)實(shí)際情況進(jìn)行調(diào)度,此種調(diào)度方式一般適用于2C的業(yè)務(wù),同時(shí)服務(wù)接口不存在不可兼容的升級(jí)

  • 特定用戶

    1、添加用戶列表或者白名單,指定列表的用戶才會(huì)進(jìn)行新版本的調(diào)度,此策略適用于發(fā)版以后本公司用戶或者測(cè)試用的定向測(cè)試和驗(yàn)證

    2、用戶比例,可以根據(jù)用戶ID進(jìn)行等比例的升級(jí)驗(yàn)證,比如5%、10%這樣的比例,然后逐步的驗(yàn)證擴(kuò)大比例

  • 關(guān)鍵字

    關(guān)鍵字過(guò)濾范圍比較廣,比如地域、手機(jī)型號(hào)、網(wǎng)絡(luò)類(lèi)型、自定義的關(guān)鍵字等都可以作為過(guò)濾的策略,此策略使用比較靈活,也比較廣泛,其中特性用戶的灰度策略是關(guān)鍵字策略的一種。

實(shí)現(xiàn)細(xì)節(jié)

Kong介紹

  • Kong誕生于2014年11月,最早是基于OpenResty(nginx+lua)實(shí)現(xiàn)的一個(gè)API網(wǎng)關(guān),基于plugin的思想開(kāi)發(fā),可以根據(jù)自己的需求定制特定的plugin

  • 隨著Kong的發(fā)展已經(jīng)升級(jí)到了2.1.x的release版本,已經(jīng)有41K GitHub Stars、53K+ Community Members、下載數(shù)200M+,而且緊跟技術(shù)前沿,可以實(shí)現(xiàn)無(wú)縫集成到kubernetes中,除了http協(xié)議,還支持了很多其他的協(xié)議,同時(shí)也實(shí)現(xiàn)了Kong Mesh,能夠在Mesh Service領(lǐng)域占有一席之地,從下圖可以看的更確切


    灰度.png

落地實(shí)現(xiàn)

  • 本公司是從Kong 1.0的版本開(kāi)始使用,當(dāng)時(shí)就是想通過(guò)Kong來(lái)作為我們的接入網(wǎng)關(guān)層,能夠?qū)崿F(xiàn)我們的灰度發(fā)布的落地,通過(guò)調(diào)研可以通過(guò)實(shí)現(xiàn)一個(gè)plugin來(lái)實(shí)現(xiàn),所以就開(kāi)始通過(guò)lua來(lái)實(shí)現(xiàn)這個(gè)plugin。

    [圖片上傳失敗...(image-5ac19e-1598260627900)]

    1、灰度調(diào)度通過(guò)Redis存儲(chǔ),通過(guò)管理平臺(tái)進(jìn)行調(diào)度測(cè)量的修改

    2、Kong-plugin,定時(shí)拉取Redis來(lái)更新灰度策略,Kong會(huì)存儲(chǔ)一份灰度策略在table中,同時(shí)增加過(guò)期時(shí)間。

    3、灰度的策略粒度不只是到Domain層,可以到URI層

    4、內(nèi)部Nginx是因?yàn)镵ong1.x版本不支持動(dòng)態(tài)upstream,只能通過(guò)內(nèi)部域名的方式來(lái)進(jìn)行調(diào)度

    5、由于是SaaS公司,本身有客戶標(biāo)識(shí),可以通過(guò)客戶標(biāo)識(shí)來(lái)進(jìn)行灰度的策略調(diào)度

    6、由于是通過(guò)Redis來(lái)進(jìn)行統(tǒng)一策略存儲(chǔ),這樣就讓Kong作為一個(gè)無(wú)狀態(tài)的方式部署,可以橫向擴(kuò)容,通過(guò)定時(shí)拉取同步保證灰度策略數(shù)據(jù)的最終一致

    7、隨著Kong的版本升級(jí),對(duì)于上述架構(gòu)也做出來(lái)一些調(diào)整,完全能夠滿足當(dāng)前業(yè)務(wù)需求,同時(shí)增加了kubernetes的ingress,所以去掉了內(nèi)部Nginx層,架構(gòu)更加的清晰

使用升級(jí)

多環(huán)境

  • 由于系統(tǒng)SaaS系統(tǒng),主要是針對(duì)2B的一些大客戶,不免有些客戶會(huì)嘗試進(jìn)行云端的系統(tǒng)隔離,考慮到APP、WEB、內(nèi)部依賴(lài)、基礎(chǔ)服務(wù)的軟件隔離,所以我們做了架構(gòu)的設(shè)計(jì),通過(guò)Kong來(lái)進(jìn)行服務(wù)之間調(diào)度的多環(huán)境隔離,那么Kong作為流量中轉(zhuǎn)層,來(lái)進(jìn)行環(huán)境的調(diào)度,同樣的調(diào)度策略,通過(guò)用戶標(biāo)識(shí)來(lái)進(jìn)行控制


    多環(huán)境.png

雙活

  • 當(dāng)前業(yè)內(nèi)分享比較多的就是餓了么的雙活架構(gòu)設(shè)計(jì),對(duì)于用戶劃區(qū),然后通過(guò)接入網(wǎng)關(guān)進(jìn)行分區(qū)之間的系統(tǒng)隔離,那么我們的雙活設(shè)計(jì)也是參考了餓了么的設(shè)計(jì),在接入層做分區(qū)的調(diào)度

  • 同樣的原因,SaaS系統(tǒng)有做分區(qū)天然的優(yōu)勢(shì),首先對(duì)客戶打標(biāo)簽,客戶的所在城市就是其中的一個(gè)標(biāo)簽,那么這個(gè)城市決定了用戶的調(diào)度地址應(yīng)該是在哪里,對(duì)于WEB端我們通過(guò)DNSPod做了一些隔離控制(準(zhǔn)確率低相對(duì)高),對(duì)于APP端我們通過(guò)自研的HttpDNS來(lái)控制訪問(wèn)的入口。但是不可避免上述兩種方式都有可能有部分流量進(jìn)入到不屬于自己的分區(qū),造成流量污染。所以我們就需要在流量接入層同時(shí)也需要做一些流量的調(diào)度控制,來(lái)確保不會(huì)有流量污染。

  • 雙活最難的就是數(shù)據(jù)層的雙寫(xiě)和隔離,但是當(dāng)前的開(kāi)源系統(tǒng)、設(shè)置于阿里云的DTS都很難保證數(shù)據(jù)雙寫(xiě)雙向同步的高保證,我們就是用的阿里云的DTS,經(jīng)常會(huì)遇到同步延時(shí)、主鍵沖突的事情發(fā)生,從而造成臟數(shù)據(jù),然后需要DBA來(lái)手動(dòng)的修復(fù)數(shù)據(jù),所以只能靠接入層來(lái)保證流量的精準(zhǔn)調(diào)度


    雙活.png

總結(jié)

  • 灰度是保證服務(wù)可用性非常重要的一個(gè)設(shè)計(jì),所以需要吃透,結(jié)合自己的業(yè)務(wù)需求能夠落地到自己的系統(tǒng)中去

  • 本文是根據(jù)自己的實(shí)際使用情況針對(duì)Kong接入層來(lái)落地的灰度發(fā)布

  • 下一篇文章會(huì)介紹基于Spring Cloud的zuul網(wǎng)關(guān)如何來(lái)實(shí)現(xiàn)灰度發(fā)布

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容