深入剖析全鏈路灰度技術(shù)內(nèi)幕(2)
發(fā)布時(shí)間:2021-12-16 點(diǎn)擊數(shù):1240
03
1
物理環(huán)境隔離
邏輯環(huán)境隔離
接下來(lái),會(huì)介紹解決上述問(wèn)題需要用到的技術(shù)。
標(biāo)簽路由通過(guò)對(duì)服務(wù)下所有節(jié)點(diǎn)按照標(biāo)簽名和標(biāo)簽值不同進(jìn)行分組,使得訂閱該服務(wù)節(jié)點(diǎn)信息的服務(wù)消費(fèi)端可以按需訪問(wèn)該服務(wù)的某個(gè)分組,即所有節(jié)點(diǎn)的一個(gè)子集。服務(wù)消費(fèi)端可以使用服務(wù)提供者節(jié)點(diǎn)上的任何標(biāo)簽信息,根據(jù)所選標(biāo)簽的實(shí)際含義,消費(fèi)端可以將標(biāo)簽路由應(yīng)用到更多的業(yè)務(wù)場(chǎng)景中。
那么如何給服務(wù)節(jié)點(diǎn)添加不同的標(biāo)簽?zāi)??在如今火熱的云原生技術(shù)推動(dòng)下,大多數(shù)業(yè)務(wù)都在積極進(jìn)行容器化改造之旅。這里,我就以容器化的應(yīng)用為例,介紹在使用 Kubernetes Service 作為服務(wù)發(fā)現(xiàn)和使用比較流行的 Nacos 注冊(cè)中心這兩種場(chǎng)景下如何對(duì)服務(wù) Workload 進(jìn)行節(jié)點(diǎn)打標(biāo)。
請(qǐng)求鏈路上各個(gè)組件如何識(shí)別出不同的灰度流量?答案就是流量染色,為請(qǐng)求流量添加不同灰度標(biāo)識(shí)來(lái)方便區(qū)分。我們可以在請(qǐng)求的源頭上對(duì)流量進(jìn)行染色,前端在發(fā)起請(qǐng)求時(shí)根據(jù)用戶信息或者平臺(tái)信息的不同對(duì)流量進(jìn)行打標(biāo)。如果前端無(wú)法做到,我們也可以在微服務(wù)網(wǎng)關(guān)上對(duì)匹配特定路由規(guī)則的請(qǐng)求動(dòng)態(tài)添加流量標(biāo)識(shí)。此外,流量在鏈路中流經(jīng)灰度節(jié)點(diǎn)時(shí),如果請(qǐng)求信息中不含有灰度標(biāo)識(shí),需要自動(dòng)為其染色,接下來(lái)流量就可以在后續(xù)的流轉(zhuǎn)過(guò)程中優(yōu)先訪問(wèn)服務(wù)的灰度版本。
還有一個(gè)很重要的問(wèn)題是如何保證灰度標(biāo)識(shí)能夠在鏈路中一直傳遞下去呢?如果在請(qǐng)求源頭染色,那么請(qǐng)求經(jīng)過(guò)網(wǎng)關(guān)時(shí),網(wǎng)關(guān)作為代理會(huì)將請(qǐng)求原封不動(dòng)的轉(zhuǎn)發(fā)給入口服務(wù),除非開(kāi)發(fā)者在網(wǎng)關(guān)的路由策略中實(shí)施請(qǐng)求內(nèi)容修改策略。接著,請(qǐng)求流量會(huì)從入口服務(wù)開(kāi)始調(diào)用下一個(gè)微服務(wù),會(huì)根據(jù)業(yè)務(wù)代碼邏輯形成新的調(diào)用請(qǐng)求,那么我們?nèi)绾螌⒒叶葮?biāo)識(shí)添加到這個(gè)新的調(diào)用請(qǐng)求,從而可以在鏈路中傳遞下去呢?
從單體架構(gòu)演進(jìn)到分布式微服務(wù)架構(gòu),服務(wù)之間調(diào)用從同一個(gè)線程中方法調(diào)用變?yōu)閺谋镜剡M(jìn)程的服務(wù)調(diào)用遠(yuǎn)端進(jìn)程中服務(wù),并且遠(yuǎn)端服務(wù)可能以多副本形式部署,以至于一條請(qǐng)求流經(jīng)的節(jié)點(diǎn)是不可預(yù)知的、不確定的,而且其中每一跳的調(diào)用都有可能因?yàn)榫W(wǎng)絡(luò)故障或服務(wù)故障而出錯(cuò)。分布式鏈路追蹤技術(shù)對(duì)大型分布式系統(tǒng)中請(qǐng)求調(diào)用鏈路進(jìn)行詳細(xì)記錄,核心思想就是通過(guò)一個(gè)全局唯一的 traceid 和每一條的 spanid 來(lái)記錄請(qǐng)求鏈路所經(jīng)過(guò)的節(jié)點(diǎn)以及請(qǐng)求耗時(shí),其中 traceid 是需要整個(gè)鏈路傳遞的。
上面我們?cè)敿?xì)介紹了實(shí)現(xiàn)全鏈路灰度所需要的幾種技術(shù),如果想為現(xiàn)有的業(yè)務(wù)接入全鏈路灰度能力,不可避免的需要為業(yè)務(wù)使用的開(kāi)發(fā)框架 SDK 進(jìn)行改造。首先,需要支持動(dòng)態(tài)路由功能,對(duì)于 Spring Cloud、Dubbo 開(kāi)發(fā)框架,可以對(duì)出口流量實(shí)現(xiàn)自定義 Filter,在該 Filter 中完成流量識(shí)別以及標(biāo)簽路由。同時(shí)需要借助分布式鏈路追蹤技術(shù)完成流量標(biāo)識(shí)鏈路傳遞以及流量自動(dòng)染色。此外,需要引入一個(gè)中心化的流量治理平臺(tái),方便各個(gè)業(yè)務(wù)線的開(kāi)發(fā)者定義自己的全鏈路灰度規(guī)則?;?SDK 實(shí)現(xiàn)方式的圖例如下:
基于 SDK 方式的弊端在于需要業(yè)務(wù)進(jìn)行 SDK 版本升級(jí),甚至?xí)婕暗綐I(yè)務(wù)代碼的變動(dòng)。企業(yè)內(nèi)部各個(gè)微服務(wù)雖然使用同一種開(kāi)發(fā)框架,但很難保證框架版本是一致的,所以不得不為每一個(gè)版本維護(hù)一份全鏈路灰度的代碼。業(yè)務(wù)代碼與 SDK 代碼緊耦合,SDK 版本迭代會(huì)觸發(fā)業(yè)務(wù)不必要的發(fā)版變更,對(duì)業(yè)務(wù)的侵入性比較強(qiáng)。
下表是三種方式對(duì)比,從多個(gè)方面進(jìn)行了對(duì)比。
3
流量入口:網(wǎng)關(guān)
在分布式應(yīng)用中,作為流量入口的網(wǎng)關(guān)是不可或缺的。在全鏈路灰度場(chǎng)景中,就要求微服務(wù)網(wǎng)關(guān)具備豐富的流量治理能力,支持服務(wù)多版本路由,支持對(duì)特定路由規(guī)則上的請(qǐng)求進(jìn)行動(dòng)態(tài)打標(biāo)。對(duì)于入口服務(wù)可見(jiàn)性問(wèn)題,網(wǎng)關(guān)需要支持多種服務(wù)發(fā)現(xiàn)方式。安全性問(wèn)題上,網(wǎng)關(guān)作為集群對(duì)外的入口可以對(duì)所有請(qǐng)求流量進(jìn)行認(rèn)證鑒權(quán),保障業(yè)務(wù)系統(tǒng)不被非法流量入侵。
全鏈路灰度的解決方案
Cloud Native
如何在實(shí)際業(yè)務(wù)場(chǎng)景中去快速落地全鏈路灰度呢?目前,主要有兩種解決思路,基于物理環(huán)境隔離和基于邏輯環(huán)境隔離。
1
物理環(huán)境隔離
物理環(huán)境隔離,顧名思義,通過(guò)增加機(jī)器的方式來(lái)搭建真正意義上的流量隔離。
邏輯環(huán)境隔離
- 鏈路上各個(gè)組件和服務(wù)能夠根據(jù)請(qǐng)求流量特征進(jìn)行動(dòng)態(tài)路由
- 需要對(duì)服務(wù)下的所有節(jié)點(diǎn)進(jìn)行分組,能夠區(qū)分版本
- 需要對(duì)流量進(jìn)行灰度標(biāo)識(shí)、版本標(biāo)識(shí)
- 需要識(shí)別出不同版本的灰度流量
接下來(lái),會(huì)介紹解決上述問(wèn)題需要用到的技術(shù)。
標(biāo)簽路由
標(biāo)簽路由通過(guò)對(duì)服務(wù)下所有節(jié)點(diǎn)按照標(biāo)簽名和標(biāo)簽值不同進(jìn)行分組,使得訂閱該服務(wù)節(jié)點(diǎn)信息的服務(wù)消費(fèi)端可以按需訪問(wèn)該服務(wù)的某個(gè)分組,即所有節(jié)點(diǎn)的一個(gè)子集。服務(wù)消費(fèi)端可以使用服務(wù)提供者節(jié)點(diǎn)上的任何標(biāo)簽信息,根據(jù)所選標(biāo)簽的實(shí)際含義,消費(fèi)端可以將標(biāo)簽路由應(yīng)用到更多的業(yè)務(wù)場(chǎng)景中。
節(jié)點(diǎn)打標(biāo)
那么如何給服務(wù)節(jié)點(diǎn)添加不同的標(biāo)簽?zāi)??在如今火熱的云原生技術(shù)推動(dòng)下,大多數(shù)業(yè)務(wù)都在積極進(jìn)行容器化改造之旅。這里,我就以容器化的應(yīng)用為例,介紹在使用 Kubernetes Service 作為服務(wù)發(fā)現(xiàn)和使用比較流行的 Nacos 注冊(cè)中心這兩種場(chǎng)景下如何對(duì)服務(wù) Workload 進(jìn)行節(jié)點(diǎn)打標(biāo)。
在使用 Nacos 作為服務(wù)發(fā)現(xiàn)的業(yè)務(wù)系統(tǒng)中,一般是需要業(yè)務(wù)根據(jù)其使用的微服務(wù)框架來(lái)決定打標(biāo)方式。如果 Java 應(yīng)用使用的 Spring Cloud 微服務(wù)開(kāi)發(fā)框架,我們可以為業(yè)務(wù)容器添加對(duì)應(yīng)的環(huán)境變量來(lái)完成標(biāo)簽的添加操作。比如我們希望為節(jié)點(diǎn)添加版本灰度標(biāo),那么為業(yè)務(wù)容器添加`spring.cloud.nacos.discovery.metadata.version=gray`,這樣框架向Nacos注冊(cè)該節(jié)點(diǎn)時(shí)會(huì)為其添加一個(gè)標(biāo)簽`verison=gray`。
流量染色
請(qǐng)求鏈路上各個(gè)組件如何識(shí)別出不同的灰度流量?答案就是流量染色,為請(qǐng)求流量添加不同灰度標(biāo)識(shí)來(lái)方便區(qū)分。我們可以在請(qǐng)求的源頭上對(duì)流量進(jìn)行染色,前端在發(fā)起請(qǐng)求時(shí)根據(jù)用戶信息或者平臺(tái)信息的不同對(duì)流量進(jìn)行打標(biāo)。如果前端無(wú)法做到,我們也可以在微服務(wù)網(wǎng)關(guān)上對(duì)匹配特定路由規(guī)則的請(qǐng)求動(dòng)態(tài)添加流量標(biāo)識(shí)。此外,流量在鏈路中流經(jīng)灰度節(jié)點(diǎn)時(shí),如果請(qǐng)求信息中不含有灰度標(biāo)識(shí),需要自動(dòng)為其染色,接下來(lái)流量就可以在后續(xù)的流轉(zhuǎn)過(guò)程中優(yōu)先訪問(wèn)服務(wù)的灰度版本。
分布式鏈路追蹤
還有一個(gè)很重要的問(wèn)題是如何保證灰度標(biāo)識(shí)能夠在鏈路中一直傳遞下去呢?如果在請(qǐng)求源頭染色,那么請(qǐng)求經(jīng)過(guò)網(wǎng)關(guān)時(shí),網(wǎng)關(guān)作為代理會(huì)將請(qǐng)求原封不動(dòng)的轉(zhuǎn)發(fā)給入口服務(wù),除非開(kāi)發(fā)者在網(wǎng)關(guān)的路由策略中實(shí)施請(qǐng)求內(nèi)容修改策略。接著,請(qǐng)求流量會(huì)從入口服務(wù)開(kāi)始調(diào)用下一個(gè)微服務(wù),會(huì)根據(jù)業(yè)務(wù)代碼邏輯形成新的調(diào)用請(qǐng)求,那么我們?nèi)绾螌⒒叶葮?biāo)識(shí)添加到這個(gè)新的調(diào)用請(qǐng)求,從而可以在鏈路中傳遞下去呢?
從單體架構(gòu)演進(jìn)到分布式微服務(wù)架構(gòu),服務(wù)之間調(diào)用從同一個(gè)線程中方法調(diào)用變?yōu)閺谋镜剡M(jìn)程的服務(wù)調(diào)用遠(yuǎn)端進(jìn)程中服務(wù),并且遠(yuǎn)端服務(wù)可能以多副本形式部署,以至于一條請(qǐng)求流經(jīng)的節(jié)點(diǎn)是不可預(yù)知的、不確定的,而且其中每一跳的調(diào)用都有可能因?yàn)榫W(wǎng)絡(luò)故障或服務(wù)故障而出錯(cuò)。分布式鏈路追蹤技術(shù)對(duì)大型分布式系統(tǒng)中請(qǐng)求調(diào)用鏈路進(jìn)行詳細(xì)記錄,核心思想就是通過(guò)一個(gè)全局唯一的 traceid 和每一條的 spanid 來(lái)記錄請(qǐng)求鏈路所經(jīng)過(guò)的節(jié)點(diǎn)以及請(qǐng)求耗時(shí),其中 traceid 是需要整個(gè)鏈路傳遞的。
邏輯環(huán)境隔離——基于 SDK
上面我們?cè)敿?xì)介紹了實(shí)現(xiàn)全鏈路灰度所需要的幾種技術(shù),如果想為現(xiàn)有的業(yè)務(wù)接入全鏈路灰度能力,不可避免的需要為業(yè)務(wù)使用的開(kāi)發(fā)框架 SDK 進(jìn)行改造。首先,需要支持動(dòng)態(tài)路由功能,對(duì)于 Spring Cloud、Dubbo 開(kāi)發(fā)框架,可以對(duì)出口流量實(shí)現(xiàn)自定義 Filter,在該 Filter 中完成流量識(shí)別以及標(biāo)簽路由。同時(shí)需要借助分布式鏈路追蹤技術(shù)完成流量標(biāo)識(shí)鏈路傳遞以及流量自動(dòng)染色。此外,需要引入一個(gè)中心化的流量治理平臺(tái),方便各個(gè)業(yè)務(wù)線的開(kāi)發(fā)者定義自己的全鏈路灰度規(guī)則?;?SDK 實(shí)現(xiàn)方式的圖例如下:
邏輯環(huán)境隔離——基于 Java Agent
基于 SDK 方式的弊端在于需要業(yè)務(wù)進(jìn)行 SDK 版本升級(jí),甚至?xí)婕暗綐I(yè)務(wù)代碼的變動(dòng)。企業(yè)內(nèi)部各個(gè)微服務(wù)雖然使用同一種開(kāi)發(fā)框架,但很難保證框架版本是一致的,所以不得不為每一個(gè)版本維護(hù)一份全鏈路灰度的代碼。業(yè)務(wù)代碼與 SDK 代碼緊耦合,SDK 版本迭代會(huì)觸發(fā)業(yè)務(wù)不必要的發(fā)版變更,對(duì)業(yè)務(wù)的侵入性比較強(qiáng)。
邏輯環(huán)境隔離——基于 Service Mesh
三種方式對(duì)比
下表是三種方式對(duì)比,從多個(gè)方面進(jìn)行了對(duì)比。
-
如果您傾向于使用無(wú)侵入式的 Java Agent 的方式,但又擔(dān)心自建帶來(lái)的穩(wěn)定性問(wèn)題,您可以選擇 MSE 微服務(wù)治理產(chǎn)品,該產(chǎn)品是阿里巴巴內(nèi)部多年在微服務(wù)治理領(lǐng)域的沉淀的產(chǎn)出,經(jīng)歷了各種大促考驗(yàn)。
- 如果您傾向于使用語(yǔ)言無(wú)關(guān)、無(wú)侵入式的 Service Mesh 的方式,但又擔(dān)心自建帶來(lái)的穩(wěn)定性問(wèn)題,您可以選擇阿里云 ASM 產(chǎn)品,相比開(kāi)源 Istio,在功能性、穩(wěn)定性和安全性都有很大的提升。
3
流量入口:網(wǎng)關(guān)
在分布式應(yīng)用中,作為流量入口的網(wǎng)關(guān)是不可或缺的。在全鏈路灰度場(chǎng)景中,就要求微服務(wù)網(wǎng)關(guān)具備豐富的流量治理能力,支持服務(wù)多版本路由,支持對(duì)特定路由規(guī)則上的請(qǐng)求進(jìn)行動(dòng)態(tài)打標(biāo)。對(duì)于入口服務(wù)可見(jiàn)性問(wèn)題,網(wǎng)關(guān)需要支持多種服務(wù)發(fā)現(xiàn)方式。安全性問(wèn)題上,網(wǎng)關(guān)作為集群對(duì)外的入口可以對(duì)所有請(qǐng)求流量進(jìn)行認(rèn)證鑒權(quán),保障業(yè)務(wù)系統(tǒng)不被非法流量入侵。