一站式動態(tài)多環(huán)境建設(shè)案例
01 問題背景
致景科技成立于 2013 年 12 月,是領(lǐng)先的紡織產(chǎn)業(yè)互聯(lián)網(wǎng)企業(yè),國家高新技術(shù)企業(yè)。旗下?lián)碛小鞍俨肌?、“全布”、“天工”、“致景金條”、“致景紡織智造園”、“致景智慧倉物流園”等業(yè)務(wù)板塊,致力于通過大數(shù)據(jù)、云計(jì)算、物聯(lián)網(wǎng)等新一代信息技術(shù),全面打通紡織服裝行業(yè)的信息流、物流和資金流,幫助行業(yè)實(shí)現(xiàn)協(xié)同化、柔性化、智能化的升級,構(gòu)建紡織服裝縱向一體化的數(shù)智化綜合服務(wù)平臺。
我們作為集團(tuán)公司已經(jīng)成立 2 年多的一個業(yè)務(wù)團(tuán)隊(duì),項(xiàng)目并行開發(fā)上線的情況越來越多。值得一提的是,我們目前處于微服務(wù)化拆分剛開始的階段,目前 35 個微服務(wù),拆完之后大概會去到 60 個左右。在這樣的背景下,原先大家都使用一套開發(fā)/測試/生產(chǎn)環(huán)境串行跑研發(fā)流程,隨著項(xiàng)目數(shù)量、開發(fā)測試需求的變多,微服務(wù)拆分的進(jìn)行,原先的方式已經(jīng)不太適合我們。下面簡單羅列一下,我們在這過程中所遇到的三個問題。
1.項(xiàng)目測試環(huán)境被搶占
最典型的問題就是一個項(xiàng)目測試環(huán)境經(jīng)常性被缺陷修復(fù)的測試流程搶占,導(dǎo)致項(xiàng)目測試時(shí)斷時(shí)續(xù),對測試而言缺乏沉浸式體驗(yàn),同時(shí)測試環(huán)節(jié)成為項(xiàng)目并行度的主要瓶頸,驗(yàn)證影響項(xiàng)目迭代的進(jìn)度。
2.開發(fā)聯(lián)調(diào)環(huán)境不穩(wěn)定
為了保證開發(fā)的體驗(yàn),開發(fā)環(huán)境是允許開發(fā)同學(xué)自由發(fā)布。由于使用一套環(huán)境,不同的同學(xué)進(jìn)行開發(fā)環(huán)境發(fā)布,經(jīng)常性地導(dǎo)致聯(lián)調(diào)中斷。不少開發(fā)同學(xué)轉(zhuǎn)而尋求端到端的線下聯(lián)調(diào),在個人機(jī)器上部署上下游應(yīng)用,這種模式在微服務(wù)化推廣之后,特別是面對眾多的微服務(wù)應(yīng)用基本上寸步難行。如何解決開發(fā)階段代碼調(diào)試的便攜性,成為了我們遇到的第二個問題。
3.線上灰度環(huán)境的缺乏
第三個問題也是最重要的,之前我們?nèi)鄙賹iT提供給產(chǎn)品經(jīng)理進(jìn)行功能驗(yàn)證的預(yù)發(fā)環(huán)境。新功能完成測試之后直接上線到線上環(huán)境,研發(fā)團(tuán)隊(duì)為了避免避免對客戶產(chǎn)生不良影響,經(jīng)常性地將發(fā)布計(jì)劃安排在晚上。拋開研發(fā)團(tuán)隊(duì)的發(fā)布幸福度不談,線上環(huán)境缺乏灰度發(fā)布能力意味著新功能上線以后就會對全量用戶放開,一旦發(fā)生了產(chǎn)品設(shè)計(jì)缺陷或者代碼漏洞的情況,那么影響面將會是全網(wǎng)的,風(fēng)險(xiǎn)巨大且不可控。
綜上所述,我們需要解決線下缺乏隔離的多套環(huán)境來支持多項(xiàng)目的開發(fā)和測試,同時(shí)在線上需要具備靈活的流量路由策略支持灰度發(fā)布需求。
02 方案調(diào)研與探索
結(jié)合我們公司實(shí)際情況,我們的目標(biāo)是開發(fā)團(tuán)隊(duì)不依賴運(yùn)維團(tuán)隊(duì),即 DEV = OPS 。我們可以一鍵拉起邏輯隔離的開發(fā)/項(xiàng)目環(huán)境,同時(shí)可以支持預(yù)發(fā)環(huán)境隔離,對于生產(chǎn)環(huán)境可以通過配置灰度規(guī)則流量、自然流量來進(jìn)行全鏈路灰度的驗(yàn)證。
根據(jù)我們對當(dāng)前問題的分析,參考目前互聯(lián)網(wǎng)上的解決方案,都指向了項(xiàng)目環(huán)境治理和服務(wù)流量治理的方案,我們稍微羅列下常用的幾種方案,我們最終選擇的是阿里云微服務(wù)引擎 MSE 全鏈路灰度 + 云效應(yīng)用交付平臺 APPSTACK 的集成方案。
1.自研 Ribbon 實(shí)現(xiàn)

我們使用的是 Spring Cloud 框架,在平時(shí)的業(yè)務(wù)開發(fā)過程中,后端服務(wù)與服務(wù)之間的調(diào)用往往通過 Fegin 或者 RestTemplate 兩種調(diào)用方式。這其中是通過 Ribbon 這個組件幫我們做了負(fù)載均衡的功能?;叶鹊暮诵木褪锹酚桑覀兛梢酝ㄟ^重寫 Ribbon 默認(rèn)的負(fù)載均衡算法,在負(fù)載均衡調(diào)用之前,增加流量路由的邏輯,那么就意味著我們能夠控制服務(wù)流量的轉(zhuǎn)發(fā)。
這個方案要實(shí)施下去,對于大廠來說確實(shí)可以從 0 到 1 再到 100 進(jìn)化出來,對我們來說,如果僅僅是實(shí)現(xiàn)一個路由的功能,做一個只支持核心場景的簡陋版確實(shí)不是非常困難的事情。但如果要達(dá)到成熟可應(yīng)用的階段,需要投入專門的技術(shù)資源對其進(jìn)行管理與維護(hù),同時(shí)由于 Spring Cloud 微服務(wù)框架本身的復(fù)雜性,隨著微服務(wù)數(shù)量逐步增多,鏈路越來越長,相關(guān)的微服務(wù)治理問題的定位與解決,也會耗費(fèi)不菲的時(shí)間成本。
2.物理隔離(藍(lán)綠發(fā)布)

這種方案需要為要灰度的服務(wù)搭建一套網(wǎng)絡(luò)隔離、資源獨(dú)立的環(huán)境,在其中部署服務(wù)的灰度版本。由于與基礎(chǔ)環(huán)境隔離,基礎(chǔ)環(huán)境中的其他服務(wù)無法訪問到需要灰度的服務(wù),所以需要在灰度環(huán)境中冗余部署這些服務(wù),以便整個調(diào)用鏈路正常進(jìn)行流量轉(zhuǎn)發(fā)。此外,注冊中心等一些其他依賴的中間件組件也需要冗余部署在灰度環(huán)境中,保證微服務(wù)之間的可?性問題,確保獲取的節(jié)點(diǎn) IP 地址只屬于當(dāng)前的網(wǎng)絡(luò)環(huán)境。這個方案需要為這些業(yè)務(wù)場景采用堆機(jī)器的方式來維護(hù)多套灰度環(huán)境,會造成運(yùn)維、機(jī)器成本過大,成本和代價(jià)遠(yuǎn)超收益;當(dāng)然如果應(yīng)用數(shù)目很小,就兩三個應(yīng)用,這個方式還是很方便的,可以接受的。
3.MSE 標(biāo)簽路由+APPSTACK 應(yīng)用編排(我們的選擇)
這兩款產(chǎn)品的說明文檔見鏈接
云效應(yīng)用交付平臺 AppStack :
https://help.aliyun.com/document_detail/321856.html
阿里云微服務(wù)引擎 MSE 全鏈路灰度 :
https://help.aliyun.com/document_detail/170454.html
我們假定通過上面的兩篇文章,讀者已經(jīng)對這兩個產(chǎn)品已經(jīng)有了簡單的了解,一句話介紹就是:APPSTACK 負(fù)責(zé)應(yīng)用的環(huán)境管理和流水線發(fā)布,MSE 負(fù)責(zé)流量的全鏈路灰度。
- MSE 全鏈路灰度的重要概念
對照下面的 MSE 標(biāo)簽路由的圖,我們重點(diǎn)介紹下 MSE 標(biāo)簽路由的幾個重要概念如應(yīng)用的打標(biāo)、流量染色/自動染色、標(biāo)識鏈路傳遞等,同時(shí)下圖也是我們采用方案的核心原理,使用域名來標(biāo)識不同的邏輯隔離環(huán)境。

核心示意圖
(1)應(yīng)用(服務(wù))打標(biāo)
對照核心示意圖,我們發(fā)現(xiàn)每個應(yīng)用都有個(base/gray)的 tag,有了這個 tag,我們才可以根據(jù) tag 定義流量規(guī)則。
我們創(chuàng)建 MSE 應(yīng)用的時(shí)候是通過特定 annotation 和環(huán)境變量給 MSE 應(yīng)用打標(biāo)的。
特定 annotation:
alicloud.service.tag=dev1
環(huán)境變量:
spring.cloud.nacos.discovery.metadata.version

增加特定的 annotation 跟環(huán)境變量
比如通過 annotation 打標(biāo)之后我們就可以在 MSE 的標(biāo)簽路由中進(jìn)行流量規(guī)則定義,同時(shí)我們也可以看到 Nacos 里面的服務(wù)有了一個標(biāo)簽相關(guān)的元數(shù)據(jù)(_micro.service.env_);

MSE 流量規(guī)則配置

Nacos 里面元數(shù)據(jù)信息
也有額外增加一個容器環(huán)境變量的做法:
spring.cloud.nacos.discovery.metadata.version
這種做法會在 Nacos 的服務(wù)元數(shù)據(jù)中增加一個 version 屬性,像 MSE 云原生網(wǎng)關(guān)就會借助這個 version 屬性進(jìn)行流量管理,而 MSE 全鏈路灰度是借助 alicloud.service.tag 定義的標(biāo)簽進(jìn)行流量管理。

容器中增加 gray 相關(guān)的環(huán)境變量

MSE 流量規(guī)則配置出現(xiàn) gray 節(jié)點(diǎn)

Nacos 里面有g(shù)ray環(huán)境的元數(shù)據(jù)信息

MSE 云原生網(wǎng)關(guān)可以選擇 gray 版本
(2) 流量染色/自動染色
簡單講,流量染色就是流量帶上了特別的標(biāo)識,對于 HTTP 請求來說,是請求頭里帶了一些標(biāo)識信息,對于 Message 來說,是消息頭里帶了標(biāo)識信息;我們這里主要講下 HTTP 流量染色問題;一種是人工的往 HTTP 請求里面增加標(biāo)識信息,比如前端請求后端 API 的時(shí)候,增加一個 xx:111 的標(biāo)識信息,那我們就說這個流量被染色了。而自動染色,則說的是一個沒有標(biāo)識的 HTTP 請求,經(jīng)由某個打了標(biāo)的 nacos 服務(wù)之后,往后調(diào)用下一個服務(wù)的時(shí)候,自動會帶上這個 nacos 服務(wù)的標(biāo)簽信息在請求頭里;最簡單的舉例就是 a 應(yīng)用調(diào)用 b(gray)應(yīng)用,那b應(yīng)用調(diào)用后面的 c 應(yīng)用的時(shí)候,會自動帶上 x-mse-tag:gray 的請求頭,這就是自動染色。
這里特別提到 x-mse-tag:xxx 這個標(biāo)識,他是 MSE 系統(tǒng)保留的標(biāo)識,不僅僅代表了染色,同時(shí)也代表了鏈路傳遞(這個請求鏈路上的各個節(jié)點(diǎn)都會依次傳遞這個標(biāo)簽下去)和默認(rèn)的路由規(guī)則(優(yōu)先選擇 xxx 標(biāo)識的服務(wù),沒有找到的情況下,再選擇 base 服務(wù)-沒有打標(biāo)的),這個默認(rèn)路由規(guī)則是不需要顯式定義的。
我們的解決方案也是特別地利用了這一點(diǎn),對照核心示意圖,我們在域名名字中添加了流量標(biāo)識,然后在 Ingress-Nginx 中將流量標(biāo)識解析出來然后通過 x-mse-tag:xxx 的方式一路傳遞下去,這樣就實(shí)現(xiàn)了在整個鏈路上優(yōu)先選擇 xxx 標(biāo)識的服務(wù),使用沒有標(biāo)識的 base 服務(wù)進(jìn)行兜底。
(3)標(biāo)識鏈路傳遞
流量被染色,也就是請求頭中有特定標(biāo)識之后,這個標(biāo)識在調(diào)用鏈路中如何可以傳遞下去,比如一個 HTTP 請求,帶了 user-id:100 的頭,陸續(xù)需要經(jīng)過 A->B->C。即調(diào)用 A 的時(shí)候帶了 user-id:100,A 調(diào)用 B 的時(shí)候也希望可以帶上 user-id:100 的請求頭,同樣 B 調(diào)用 C 的時(shí)候也要帶上 user-id:100。這個就是標(biāo)識的鏈路傳遞,有了這個標(biāo)識鏈路傳遞,我們才可以在為 A/B/C 應(yīng)用定義按 user-id 的值進(jìn)行路由的策略。MSE 的標(biāo)識鏈路傳遞的方法是定義環(huán)境變量 alicloud.service.header=x-user-id,在入口應(yīng)用 A(所有版本,gray+base)增加該環(huán)境變量以后,往后的調(diào)用 B 和 C 的過程中,都會自動添加請求頭 x-user-id 進(jìn)行傳遞,這樣就方便我們在 A,B,C 節(jié)點(diǎn)按照特有規(guī)則進(jìn)行路由定義。當(dāng)然 x-mse-tag 這個特殊的請求頭默認(rèn)就是鏈路傳遞的,MSE 會把這個標(biāo)識層層傳遞下去并進(jìn)行默認(rèn)的路由規(guī)則(tag 優(yōu)先,base 兜底);MSE 標(biāo)識鏈路傳遞的原理如下,借助分布式鏈路追蹤的框架的實(shí)現(xiàn)方式,每個應(yīng)用的探針攔截請求并解析標(biāo)識,然后暫存到線程空間,在往后調(diào)用的時(shí)候再通過探針把標(biāo)識塞到下個請求。通過分布式鏈路追蹤的框架完成標(biāo)識傳遞。

- 阿里云效應(yīng)用交付 APPSTACK 簡述
我們把云效 APPSTACK 引入進(jìn)來,主要目的是方便開發(fā)同學(xué)通過白屏的管理方式自助完成 MSE 所需要的配置工作,同時(shí)在微服務(wù)架構(gòu)下,我們希望應(yīng)用進(jìn)行拆分之后,每個應(yīng)用都有自己的 owner。

通過 APPSTACK 我們可以屏蔽 K8s 的 deployment,service,ingress 等細(xì)節(jié),研發(fā)同學(xué)面向的就是應(yīng)用+環(huán)境+流水線。這樣最終開發(fā)人員在 APPSTACK 通過流水線完成應(yīng)用的環(huán)境部署,每個環(huán)境都會按照 MSE 標(biāo)簽路由的要求打上不同的標(biāo)識。

應(yīng)用的多套環(huán)境部署
圖片每個環(huán)境都會按照 MSE 標(biāo)簽路由的要求打上不同的標(biāo)識
在這里我們不展開講述 APPSTACK 的核心功能,我們這里主要的就是借助應(yīng)用編排,讓每個應(yīng)用的每個環(huán)境部署的時(shí)候,可以設(shè)置好 MSE 標(biāo)簽路由所需要的各種環(huán)境變量和 annotation。
03 我們的解決方案
我們在調(diào)研了以上能力之后,根據(jù)自己公司的實(shí)際場景與業(yè)務(wù)需求,根據(jù)不同環(huán)境的特性,定義了多種環(huán)境的抽象,基于此構(gòu)建了一站式動態(tài)多環(huán)境的能力,并針對主要場景設(shè)計(jì)了不同的實(shí)施方案。
1 環(huán)境定義
通過對阿里云微服務(wù)引擎 MSE 標(biāo)簽路由和云效應(yīng)用編排 APPSTACK 的調(diào)研,結(jié)合我們前面提到所面臨的問題,我們最終定義了我們整個研發(fā)體系所需要的環(huán)境體系即:多套的開發(fā)環(huán)境(含基礎(chǔ)環(huán)境)+多套項(xiàng)目環(huán)境(含基礎(chǔ)環(huán)境)+(集成)測試環(huán)境+預(yù)發(fā)環(huán)境+(支持灰度)生產(chǎn)環(huán)境,如下圖

多套開發(fā)環(huán)境:目標(biāo)是支持多個項(xiàng)目的在開發(fā)階段的開發(fā)聯(lián)調(diào),核心要求是各項(xiàng)目動態(tài)隔離并且支持端云互聯(lián),項(xiàng)目動態(tài)隔離是每個項(xiàng)目都有自己的開發(fā)聯(lián)調(diào)環(huán)境且只需部署有變動應(yīng)用,端云互聯(lián)是開發(fā)可以將自己本地跑的應(yīng)用注冊到這個 MSE 這個體系里面來,實(shí)現(xiàn)可以本地調(diào)試的目的,兩個研發(fā)可以點(diǎn)對點(diǎn)地進(jìn)行本地 debug 來跟蹤問題。開發(fā)基礎(chǔ)環(huán)境是負(fù)責(zé)兜底服務(wù)調(diào)用的,每個應(yīng)用生產(chǎn)部署之后都需要同步更新開發(fā)基礎(chǔ)環(huán)境,保障基礎(chǔ)環(huán)境是最新的生產(chǎn)版本。
多套項(xiàng)目環(huán)境:目標(biāo)是支持耗時(shí)較長的大型項(xiàng)目,比如重大技改,重大業(yè)務(wù)項(xiàng)目,需要長時(shí)間占用測試環(huán)境跟內(nèi)外部關(guān)聯(lián)方進(jìn)行穩(wěn)定測試的。核心要求是各個項(xiàng)目動態(tài)隔離。關(guān)于項(xiàng)目動態(tài)隔離的定義同上。
測試環(huán)境:目標(biāo)是支持短平快的項(xiàng)目測試和集成測試,比如日常的缺陷修復(fù),或者多個小項(xiàng)目需要集成到一起發(fā)布,同時(shí)也是我們?nèi)粘W詣踊瘻y試的環(huán)境。項(xiàng)目環(huán)境中的特性分支也需要經(jīng)過測試環(huán)境的自動化測試才可以上線。
預(yù)發(fā)環(huán)境:目標(biāo)是支持產(chǎn)品經(jīng)理在真實(shí)環(huán)境中驗(yàn)證產(chǎn)品功能,進(jìn)行驗(yàn)收,預(yù)發(fā)環(huán)境使用的基礎(chǔ)建設(shè)如數(shù)據(jù)庫等同生產(chǎn)環(huán)境是一致的,當(dāng)然這里對系統(tǒng)設(shè)計(jì)也會提出更高的要求,比如需要保持向前兼容,就像數(shù)據(jù)庫,只能增列不能減列,不能在 sql 中使用 select * 等等,這些我們通過 DMS 進(jìn)行數(shù)據(jù)庫結(jié)構(gòu)變更的約束和通過代碼檢查保障,此處不贅述。
生產(chǎn)環(huán)境:目標(biāo)是支持規(guī)則流量+自然流量的全鏈路灰度,這里的規(guī)則流量指的是帶有明顯特征的流量,通過 MSE 的流量規(guī)則能夠清晰定義的請求,比如請求頭,參數(shù),cookie,body 中數(shù)據(jù)符合規(guī)則的。自然流量則相反,我們不指定任何特征,比如全部流量的 1%導(dǎo)入到灰度環(huán)境,這個我們就理解成自然流量。
綜合來看,目前的環(huán)境體系里,開發(fā)環(huán)境和項(xiàng)目環(huán)境涉及到動態(tài)隔離,所以需要部署基礎(chǔ)環(huán)境來完成服務(wù)兜底的能力,這個基礎(chǔ)環(huán)境也就是 MSE 標(biāo)簽路由中無標(biāo)簽(base)應(yīng)用的提供者。
這一套環(huán)境體系的流轉(zhuǎn)流程主要有:
1. 拉取特性分支進(jìn)入開發(fā)環(huán)境進(jìn)行本地開發(fā)和前后端聯(lián)調(diào),然后提測到項(xiàng)目環(huán)境
2. 項(xiàng)目環(huán)境由測試團(tuán)隊(duì)完成功能測試之后,將應(yīng)用部署到(集成)測試環(huán)境
3. 在(集成)測試環(huán)境同其他特性分支一起完成集成,并通過自動化測試和簡單驗(yàn)證,就可以部署至預(yù)發(fā)環(huán)境
4. 產(chǎn)品經(jīng)理在預(yù)發(fā)環(huán)境進(jìn)行功能驗(yàn)收測試,通過之后可以發(fā)布到生產(chǎn)環(huán)境進(jìn)行灰度驗(yàn)證
5. 在生產(chǎn)環(huán)境可以按照規(guī)則流量+自然流量進(jìn)行灰度驗(yàn)證,通過之后就可以導(dǎo)入全部流量
6. 最后將特性分支合并至主干后用最新的生產(chǎn)版本更新開發(fā)/項(xiàng)目基礎(chǔ)環(huán)境。
2.主要場景實(shí)施
- 場景一:項(xiàng)目隔離的動態(tài)多環(huán)境
按照我們的解決方案,項(xiàng)目環(huán)境要實(shí)現(xiàn)的是邏輯隔離的動態(tài)多環(huán)境,相當(dāng)于每個應(yīng)用我們要通過 APPSTACK 部署基礎(chǔ)環(huán)境(負(fù)責(zé)兜底的無標(biāo)簽 base 應(yīng)用)和動態(tài)項(xiàng)目環(huán)境(有變更的)同時(shí)我們需要保障前端調(diào)用后端的域名可以轉(zhuǎn)換成 x-mse-tag 的請求頭。

1. 通過 APPSTACK 部署好有標(biāo)簽的應(yīng)用(項(xiàng)目環(huán)境)和沒標(biāo)簽的應(yīng)用(基礎(chǔ)環(huán)境),下列截圖僅做示范


2. 在 ingress-nginx 中解析域名中的 tag 屬性轉(zhuǎn)換成 x-mse-tag 請求頭鏈路傳遞,通過 ingress 配置攜帶 header 方式到 api 網(wǎng)關(guān)。

通過注解
nginx.ingress.kubernetes.io/configuration-snippet 實(shí)現(xiàn),具體如下:
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: proxy_set_header x-mse-tag dev1
通過這樣簡單配置之后,前端調(diào)用后端服務(wù)的時(shí)候,只要通過特定的域名請求,那 ingres-nginx 就可以把這個域名對應(yīng)的請求自動添加一個 x-mse-tag 的請求傳遞到 api 網(wǎng)關(guān)應(yīng)用,然后借助這個 x-mse-tag 的特殊請求頭,在調(diào)用下游服務(wù)的時(shí)候,就會一路優(yōu)先選擇 dev1 標(biāo)簽的服務(wù),沒有 dev1 標(biāo)簽的服務(wù)就會去找兜底的 base 服務(wù)。
- 場景二:規(guī)則流量全鏈路灰度的生產(chǎn)環(huán)境
1. 通過 APPSTACK 在生產(chǎn)環(huán)境部署好有灰度標(biāo)識的應(yīng)用。
2. 定義流量路由規(guī)則,在 MSE 控制臺為本次灰度鏈路中的入口應(yīng)用設(shè)置流量路由規(guī)則,比如本次發(fā)布更新了 A-B-C 三個應(yīng)用,A 就是入口應(yīng)用。


通過這種方式定義之后,我們可以設(shè)置符合某些特征的流量進(jìn)入到 A 應(yīng)用的 gray 版本,并且向后層層傳遞過去,不用每個應(yīng)用重復(fù)設(shè)置路由規(guī)則。這就會滿足了規(guī)則流量的全鏈路灰度的要求。
- 場景三:自然流量全鏈路灰度的生產(chǎn)環(huán)境
1. 通過APPSTACK在生產(chǎn)環(huán)境部署好有灰度標(biāo)識的應(yīng)用,略圖。這里至少需要為本次項(xiàng)目的入口應(yīng)用 A(也可以是全部應(yīng)用)增加一個自動染色的變量 profiler.micro.service.tag.trace.enable=true,這個變量會把經(jīng)過這個入口應(yīng)用 A 的流量自動染色,往后傳遞的時(shí)候自動增加 x-mse-tag 的請求頭,從而實(shí)現(xiàn)全鏈路灰度
2. 定義流量規(guī)則,即自然流量的多少比例進(jìn)入 gray 環(huán)境


這樣通過入口應(yīng)用的自動染色,以及入口應(yīng)用的自然流量分批,我們就可以讓進(jìn)入到入口應(yīng)用 gray 節(jié)點(diǎn)的自然流量進(jìn)入到全鏈路的灰度環(huán)境(灰度優(yōu)先,基礎(chǔ)應(yīng)用兜底)。
目前為止,我們實(shí)現(xiàn)了默認(rèn)按照域名進(jìn)行項(xiàng)目/開發(fā)多環(huán)境邏輯動態(tài)隔離的效果;同時(shí)提供給研發(fā)團(tuán)隊(duì)便捷的白屏管理的工具,可以由項(xiàng)目組獨(dú)立拉起整個環(huán)境,通過三個場景化的實(shí)施方案,完美解決了開篇提到的三個問題。
3.相關(guān)技術(shù)原理概要介紹
MSE + APPSTACK 的解決方案,核心的地方在于流量規(guī)則的定義以及流量標(biāo)識的傳遞,其核心的解決方案在于流量中標(biāo)識的解析和傳遞,我們再看一次這個標(biāo)識傳遞的圖:

怎么樣才能實(shí)現(xiàn)這里面最核心的解析 Extract 和注入 Inject 的功能呢?
答案是探針,為每個 MSE 管理的應(yīng)用運(yùn)行時(shí)候增加一個 java agent 的探針,完成一個類似 JVM AOP 的能力,在 ACK(K8s)的容器中,MSE 通過如下的方式自動為應(yīng)用安裝 java agent;
1. 配置 Webhook,然后根據(jù) Pod 或者 Namespac中的 Labels,來判斷是否要掛載 Java Agent。如果需要掛載,則就對 Pod 的聲明?件做出后續(xù)修改
2. 獲取并添加環(huán)境變量 JAVA_TOOL_OPTIONS,?于加載 Java Agent。
3. 給業(yè)務(wù)容器添加 Volume,?于存儲 Java Agent 的?件內(nèi)容。
4. 給 Pod 添加 Init container,?于在業(yè)務(wù)容器啟動前下載 Java Agent
最終我們每個被 MSE 管理的應(yīng)用在 POD 層面可以看到如下信息:

有了這個探針,我們可以攔截所有 HTTP REQUEST 的處理類,將我們關(guān)心的標(biāo)識信息暫存起來,然后在應(yīng)用內(nèi)部消費(fèi) Nacos 服務(wù)的時(shí)候增加 MSE 支持的路由邏輯,選擇合適的服務(wù) provider(比如是打了 gray 標(biāo)的),同時(shí)在調(diào)用這個 provider 的服務(wù)的時(shí)候,可以將暫存的流量標(biāo)識帶在請求頭里繼續(xù)傳遞下去,大體上跟我們最開始提到的自研 Ribbon 的方式相似。不過 MSE 在這塊做得比較成熟,同時(shí)不單單支持了 HTTP REST 這種服務(wù)調(diào)用方式,還包括了 Dubbo、RocketMQ 的消息灰度、數(shù)據(jù)庫灰度等。當(dāng)然全鏈路灰度僅僅是微服務(wù)引擎 MSE 一個很小的功能,微服務(wù)引擎 MSE(Microservices Engine)是一個面向業(yè)界主流開源微服務(wù)生態(tài)的一站式微服務(wù)平臺,提供注冊配置中心(原生支持 Nacos/ZooKeeper/Eureka)、云原生網(wǎng)關(guān)(原生支持 Ingress/Envoy)、微服務(wù)治理(原生 支持Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服務(wù)治理規(guī)范)的能力,有興趣的同學(xué)可以看看官方文檔。
04 借事修人
作為創(chuàng)業(yè)團(tuán)隊(duì)來講,能夠快速具備一站式解決服務(wù)治理問題,是一件非??岬氖?。這整個方案的討論實(shí)施過程中,研發(fā)團(tuán)隊(duì)對于 K8s、Nginx Ingress、MSE 都有較深入的理解。“像我們部門研發(fā)團(tuán)隊(duì),沒有專門的運(yùn)維團(tuán)隊(duì),每個開發(fā)人員都可以深入了解每個產(chǎn)品的來龍去脈,想想就很有意義。”



























