本文轉(zhuǎn)載自公眾號
三維家技術(shù)實踐
的服務(wù)治理系列文章
1 背景
目前瑞凑,微服務(wù)架構(gòu)是互聯(lián)網(wǎng)企業(yè)的標配,從單體架構(gòu)到微服務(wù)架構(gòu)秩铆,服務(wù)的數(shù)量急劇膨脹,且相互之間依賴錯綜復(fù)雜祟滴。服務(wù)治理唁盏,對開發(fā)、運維都是一個嚴峻的考驗灿里。
例如,在開發(fā)過程中程腹,為了趕進度匣吊,一個服務(wù)往往有多個Feature版本在并行開發(fā)。那么寸潦,同一個服務(wù)的多個版本如何在開發(fā)聯(lián)調(diào)色鸳、測試中做到互不影響呢?
最簡單粗暴的一種方案是建設(shè)多套開發(fā)见转、測試環(huán)境命雀,各環(huán)境有獨立的注冊中心、配置中心斩箫、服務(wù)集群以及相關(guān)中間件吏砂。顯然撵儿,這種等同物理隔離的方式,硬件成本高赊抖,維護成本大统倒,而且需要建設(shè)多少套才夠用? 恐怕沒有確定的答案氛雪。
所以,如何通過一種輕量的模式耸成,既可以滿足我們多版本并行開發(fā)和測試的需要报亩,又可以兼顧低成本和易維護呢?
抽象引申一下井氢,就是我們需要有一套低成本的弦追、滿足多版本服務(wù)并行在同一個服務(wù)集群的機制,該機制除了滿足開發(fā)花竞、測試的需要外劲件, 還能在生產(chǎn)環(huán)境中實現(xiàn)新老版本并行,也就是灰度發(fā)布
的需求约急。
2 需求
讓我們再來理一下需求:
- 在開發(fā)階段零远,需要保證多版本并行開發(fā)和聯(lián)調(diào)。
- 在測試階段厌蔽,需要保證多版本并行測試牵辣。
- 在發(fā)布階段,需要灰度發(fā)布機制奴饮,保證產(chǎn)品平滑過渡纬向。
基于上述的背景和需求,我們嘗試通過標簽路由
來解決這個問題戴卜。
3 設(shè)計思路
我們從服務(wù)路由標簽的定義逾条、原理以及常見路由規(guī)則設(shè)置這三方面進行闡述。
3.1 服務(wù)路由標簽的定義
每個服務(wù)在啟動時投剥,都會被賦予一個用于識別其版本的標簽, 我們稱之為服務(wù)路由標簽, 一般采用迭代版本號作為標簽, 例如feature-V0506
师脂。 如果沒有賦予,則默認為default
薇缅。該標簽會作為服務(wù)的一個元數(shù)據(jù)危彩,隨著服務(wù)節(jié)點信息注冊到注冊中心上。
例如上圖泳桦,我們的開發(fā)環(huán)境dev
汤徽, 包括一個注冊中心,以及一套穩(wěn)定的服務(wù)集群(其路由標簽均為default
)灸撰,包括building谒府、usercenter拼坎、material等服務(wù)。
然后程序猿A在本地開發(fā)building
服務(wù)的名為F_1
的特性分支完疫, 其對應(yīng)的路由標簽也為F_1
泰鸡,且已經(jīng)注冊到注冊中心了;程序猿B在本地開發(fā)building
服務(wù)的F_2
特性分支壳鹤, 其對應(yīng)的路由標簽也為F_2
盛龄。
這時候我們看到, 該服務(wù)在注冊中心中有3個版本芳誓,分別為穩(wěn)定的默認版本default
余舶,F_1
以及F_2
。
服務(wù)的路由標簽
R-Label
锹淌,可在服務(wù)的啟動參數(shù)或者環(huán)境變量中設(shè)置匿值。
穩(wěn)定版本,一般為生產(chǎn)上的版本(對應(yīng)
master
分支)
3.2 服務(wù)路由標簽的原理
上一節(jié)我們已經(jīng)講述了路由標簽作為元數(shù)據(jù)赂摆,會隨服務(wù)信息注冊到注冊中心上挟憔,那么它有什么用呢?
我們在調(diào)用鏈的頭部(一般為網(wǎng)關(guān)烟号,或者在非生產(chǎn)環(huán)境下為postMan
绊谭、swagger
文檔站點甚至curl
等),根據(jù)一定規(guī)則把路由標簽設(shè)置到請求頭中 (請求頭key為R-Label
褥符,一個請求最多帶一個標簽龙誊,沒有則默認為default
),這個請求頭將會作為一個染色
字段在整個調(diào)用鏈路中透傳喷楣。
那么在服務(wù)的路由選擇邏輯中趟大,我們會優(yōu)先選擇版本跟請求的標簽值相同的節(jié)點。如果找不到相同標簽的節(jié)點铣焊,就選擇default
的服務(wù)節(jié)點逊朽。
例如上述程序猿A,其本地building
服務(wù)版本為F_1
曲伊,該服務(wù)的接口A依賴usercenter
以及material
兩個服務(wù)叽讳。那么在自測的時候,其調(diào)用鏈路是
前端(postMan/swagger等)->apiGateway->building->usercenter->material
這時坟募,程序猿A在前端(手動)或者apiGateway
(通過染色規(guī)則)中加上染色字段R-Label:F_1
岛蚤,那么apiGateway
在選擇building
節(jié)點的時候,選擇了路由標簽為F_1
的節(jié)點(也就是程序猿A的本地節(jié)點)懈糯,其最終調(diào)用路徑為:
前端(postMan/swagger等)->apiGateway->building.F_1->usercenter.default->material.default
同理涤妒, 程序猿B在自測的時候,其最終調(diào)用路徑為:
前端(postMan/swagger等)->apiGateway->building.F_2->usercenter.default->material.default
還記得我們上一篇關(guān)于鏈路染色的服務(wù)治理文章嗎赚哗?本篇也是其落地場景之一
3.3 路由規(guī)則
路由規(guī)則設(shè)置在配置中心她紫,并實時推送至網(wǎng)關(guān)硅堆,它是網(wǎng)關(guān)對請求做整形的依據(jù)之一。
在網(wǎng)關(guān)中贿讹,我們根據(jù)路由規(guī)則渐逃, 給特定的請求打上特定的路由標簽,并作為染色字段透傳到整個服務(wù)集群民褂。
路由規(guī)則暫時支持如下幾種:
3.3.1 組Id路由
gId match 'G0168' => L'feature-V0506'
gId match 'G0235' => L'feature-V0506'
表示根據(jù)gId
進行打標茄菊,當請求的gId
請求頭等于G0168
或者G0235
時,給請求加上請求頭(染色字段): R-Label:feature-V0506
3.3.2 用戶uId路由
uId match 1024 => L'feature-V0506'
表示根據(jù)uId
進行灰度赊堪,當請求的uId
為1024
時买羞,給請求加上請求頭(染色字段): R-Label:feature-V0506
uId match %'10n+1' => L'feature-V0506'
表示uId
與10取模結(jié)果為1時,執(zhí)行請求整形雹食,相當于1/10的用戶訪問指定版本的服務(wù)
uId match %'10n+3..5' => L'feature-V0506'
表示uId
與10取模結(jié)果為3到5的用戶,執(zhí)行請求整形期丰,相當于3/10的用戶訪問指定版本的服務(wù)
路由規(guī)則暫只支持基于特定請求頭的規(guī)則
請求整形群叶,是指在請求處理前,改變請求的內(nèi)容(通常是增加請求頭字段)
4 應(yīng)用場景
4.1 多版本開發(fā)聯(lián)調(diào)
- 開發(fā)環(huán)境部署相對穩(wěn)定的版本(一般為
master
分支) - 本地和開發(fā)環(huán)境共用注冊中心
程序猿B和程序猿C進行本地聯(lián)調(diào)的時候钝荡,給各自服務(wù)加上R-Label:F_2
(通過環(huán)境變量或啟動參數(shù)的方式)街立,那么服務(wù)在請求的路由選址的時候,會優(yōu)先選擇選擇B跟C的本地服務(wù)埠通。如果找不到相同標簽赎离,就選擇默認default的服務(wù)節(jié)點。
4.2 多版本測試
- 測試環(huán)境中部署相對穩(wěn)定的版本(一般為
master
分支) - 不同迭代版本采用不同的路由標簽
甚至端辱,我們可以把開發(fā)環(huán)境跟測試環(huán)境合并為一個梁剔,保持環(huán)境的獨立性的同時,進一步節(jié)約了成本舞蔽。
4.2 線上灰度
- 灰度版本部署荣病,添加灰度版本的路由標簽(例如
R-Label:F_B
) - 線上灰度,支持不同維度(如
gId
渗柿、uId
)動態(tài)配置路由規(guī)則个盆。
如上圖,當請求Req1通過網(wǎng)關(guān)gateway
朵栖,網(wǎng)關(guān)會檢查路由規(guī)則颊亮,如果匹配上某個路由規(guī)則,就會往該請求添加請求頭R-Label:F_B
陨溅。 - 網(wǎng)關(guān)
gateway
選擇服務(wù)轉(zhuǎn)發(fā)節(jié)點的時候终惑,優(yōu)先選擇路由標簽R-Label
相同的服務(wù)節(jié)點,如果找不到声登,兜底操作選擇default的默認服務(wù)節(jié)點狠鸳。
5 總結(jié)
本文介紹了
標簽路由
在三維家的實踐揣苏,從設(shè)計思路和場景進行了闡述。標簽路由
解決了多版本開發(fā)聯(lián)調(diào)件舵、多版本迭代測試和線上灰度問題卸察,減少部署環(huán)境,節(jié)約人力成本和硬件成本铅祸。