前言
Spring Cloud Tencent 微服務開發框架自六月底正式對外宣發后,受到了許多開發者非常火熱的關注。不到一個月時間, Github Star 數就已突破 2000,超過 1000 名開發者加入我們的社群,并有 20 多個開發者參與貢獻項目代碼,項目的熱門程度極大地超出我們的預期,同時也驗證了我們在最初宣發文章里的觀點:Spring Boot + Spring Cloud 仍是當前使用相當廣泛開發框架。
在這一個月時間里,Spring Cloud Tencent 的關注者們最關心的問題就是,Spring Cloud Tencent 后續規劃是什么?
在過去的一段時間,我們的主要精力聚焦在微服務領域最基本的服務治理原子能力,例如服務發現、動態配置、限流熔斷、路由等。Spring Cloud 其它套件基本上也局限于這些基礎能力。但是企業真正在實踐 Spring Cloud 過程中,發現針對自身具體的業務場景,這些原子能力并不能直接提供解決方案,往往需要做二次開發、定制等。例如定制 Spring Cloud Gateway 的 Filter、增強 Feign、支持各種復雜的服務路由場景等。因此,開箱即用的業務通用解決方案對企業來說更具有價值。
綜上所述, Spring Cloud Tencent 后續重要的規劃之一就是在不斷夯實服務治理原子能力的基礎上,提供開箱即用的業務通用解決方案,從工具到方案的升級。
為此 Spring Cloud Tencent 新增了 spring-cloud-tencent-plugin-starts 模塊,在此模塊下實現不同業務場景的解決方案。現階段我們主要聚焦在精細化流量治理能力場景化方案上,并按照開發流程拆分為三個階段:
開發測試階段的多測試環境場景
發布階段的金絲雀發布、藍綠發布、全鏈路灰度等
生產運行階段的單元化、AB測試等
本期我們主要聊聊開發測試階段的多測試環境場景實戰,詳細介紹 Spring Cloud Tencent 實現多測試環境場景的方案。
一、基礎知識
1.1 什么是測試環境路由
在實際的開發過程中,一個微服務架構系統下的不同微服務可能是由多個團隊進行開發與維護的,每個團隊只需關注所屬的一個或多個微服務,而各個團隊維護的微服務之間可能存在相互調用關系。如果一個團隊在開發其所屬的微服務,調試的時候需要驗證完整的微服務調用鏈路。此時需要依賴其他團隊的微服務,如何部署開發聯調環境就會遇到以下問題:
如果所有團隊都使用同一套開發聯調環境,那么一個團隊的測試微服務實例無法正常運行時,會影響其他依賴該微服務的應用也無法正常運行。
如果每個團隊有單獨的一套開發聯調環境,那么每個團隊不僅需要維護自己環境的微服務應用,還需要維護其他團隊環境的自身所屬微服務應用,效率大大降低。同時,每個團隊都需要部署完整的一套微服務架構應用,成本也隨著團隊數的增加而大大上升。
此時可以使用測試環境路由的架構來幫助部署一套運維簡單且成本較低開發聯調環境。測試環境路由是一種基于服務路由的環境治理策略,核心是維護一個穩定的基線環境作為基礎環境,測試環境僅需要部署需要變更的微服務。多測試環境有兩個基礎概念,如下所示:
基線環境(Baseline Environment): 完整穩定的基礎環境,是作為同類型下其他環境流量通路的一個兜底可用環境,用戶應該盡量保證基線環境的完整性、穩定性。
測試環境(Feature Environment): 一種臨時環境,僅可能為開發/測試環境類型,測試環境不需要部署全鏈路完整的服務,而是僅部署本次有變更的服務,其他服務通過服務路由的方式復用基線環境服務資源。
部署完成多測試環境后,開發者可以通過一定的路由規則方式,將測試請求打到不同的測試環境,如果測試環境沒有相應的微服務處理鏈路上的請求,那么會降級到基線環境處理。因此,開發者需要將開發新測試的微服務部署到對應的測試環境,而不需要更新或不屬于開發者管理的微服務則復用基線環境的服務,完成對應測試環境的測試。
雖然測試環境路由是一個相對成熟的開發測試環境解決方案,但是能夠開箱即用的生產開發框架卻不多,往往需要開發者二次開發相應的功能。因此需要一個相對完善的解決方案來幫助實現測試環境路由,簡化開發難度并提升開發效率。
1.2 服務路由
服務路由模型
服務路由抽象出最簡化的模型如下圖所示,解決的是 “哪些請求轉發到哪些實例” 的問題。細化來看,包含三個問題:1. 如何精確標識請求?2. 如何精確標識實例?3. 如何轉發?
(圖:服務路由模型示意圖)
在流量的微觀世界里,統一通過標簽(屬性)來標識一個實體,例如請求有來源調用服務、目標環境標簽等,服務實例則有版本號、實例分組、環境分組等標簽。服務路由則是將滿足標簽匹配條件的請求轉發到滿足匹配條件的服務實例。所以服務路由的模型可拆解出如下的的專業術語:
服務實例染色 (為服務實例設置標簽信息)
流量染色(為請求設置標簽信息)
服務路由(根據路由策略,把請求轉發到目標實例)
服務實例標簽如何傳遞到調用方
服務實例注冊到注冊中心時,會帶上標簽信息。服務調用方從注冊中心獲取到服務實例信息就包含了實例的標簽信息。
標簽全鏈路透傳
有一類請求標簽數據需要在業務響應鏈路上一直傳遞,例如全鏈路追蹤里的 TraceId 、測試環境路由的 FeatureEnv 標簽等。
服務路由和負載均衡的區別
服務路由和負載均衡都是解決選擇服務實例的問題。區別在于服務路由是從全量的服務實例中挑選出一批滿足路由規則的服務實例,而負載均衡則是從路由匹配之后的服務實例列表中挑選出一個適合處理請求的實例。
二、測試環境路由實現原理
2.1 方案總覽
測試環境路由的樣例實現以下圖為例,一共有兩個測試環境以及一個基線環境。流量從端到端會依次經過以下組件:App -> 網關 -> 用戶中心 -> 積分中心 -> 活動中心。
圖:測試環境路由示意圖
根據上一節服務路由章節所述,為了達到測試環境路由的能力,開發工作需要做三件事情:
服務實例染色(標識實例屬于哪個測試環境)
流量染色(標識請求應該被轉發到哪個測試環境)
服務路由 a. 網關根據請求的目標測試環境標簽轉發到對應的目標測試環境的用戶中心。 b. 服務調用時,優先轉發到同測試環境下的目標服務實例,如果同測試環境下沒有服務實例則轉發到基線環境。
以下三小節,將會詳細介紹這三部分的原理。
2.2 服務實例染色
在多測試環境的場景中,需要對每個測試環境部署的實例進行區分,因此需要在實例上打
方式一:配置文件
在 Spring Boot 的 application.yml 配置文件里配置以下內容即可實現染色:
spring: cloud: tencent: metadata: content: idc:shanghai env:f1
Spring Cloud Tencent 應用在啟動時,讀取配置文件并解析出 idc=shanghai 和 env=f1 標簽信息。
如果以上配置文件放在項目源碼里,要實現不同的實例具有不同的標簽值則需要打不同包。可以通過以下兩種方式實現同一個運行包設置不同的標簽值:
通過 -D 啟動參數覆蓋,例如:-Dspring.cloud.tencent.metadata.content.idc=guangzhou
通過 Spring Boot 標準方式,把application.yml外掛本地磁盤上
方式二:環境變量
環境變量在容器場景下非常方便,Spring Cloud Tencent 約定了前綴為 SCT_METADATA_CONTENT_ 的環境變量為實例的標簽信息,例如:
SCT_METADATA_CONTENT_IDC=shanghai
SCT_METADATA_CONTENT_ENV=f1
Spring Cloud Tencent 應用在啟動時,自動會讀取環境變量并解析出 IDC=shanghai 和 ENV=f1 標簽信息。
方式三:自定義實現 SPI
前面兩種方式為 Spring Cloud Tencent 內置的方式,但是不一定符合每個生產項目的規范,因此 Spring Cloud Tencent 還提供了一種允許開發者自定義標簽 Provider 的方式。例如以下兩種實踐場景:
把實例標簽放到機器上的某一個配置文件里,例如 /etc/metadata。
應用啟動時,調用公司的 CMDB 接口獲取元信息。
這種場景下,只要實現 InstanceMetadataProvider SPI 擴展即可。
2.3 流量染色
流量染色即為每個請求打上目標測試環境標簽,路由轉發時根據請求標簽匹配目標服務實例。而流量染色可以分為以下幾種方式:
方式一:靜態染色
2.2 小節介紹了可以為服務實例設置一系列的標簽信息,例如 idc=shanghai、env=f1 等。在有些場景下,期望所有經過當前實例的請求都帶上當前實例的標簽信息。例如經過 env=f1 的實例的請求都攜帶 env=f1 的標簽信息。
服務實例染色有三種方式,對應的定義哪些標簽需要作為請求標簽透傳到鏈路上也有三種方式,核心思想就是定義需要全鏈路傳遞的標簽鍵值對的鍵列表。
通過配置文件的 spring.cloud.tencent.metadata.content.transitive=["idc", "env"] 配置項指定
通過 SCT_METADATA_CONTENT_TRANSITIVE=IDC,ENV 環境變量指定
通過實現 InstanceMetadataProvider#getTransitiveMetadataKeys() 方法指定
方式二:動態染色
靜態染色是把服務實例的某些標簽作為請求標簽,服務實例標簽相對靜態,應用啟動后初始化一次之后就不再變更。但是在實際的應用場景下,不同的請求往往需要設置不同的標簽信息。此時則需要通過動態染色的能力。
為請求動態染色也非常簡單,只需增加以 X-Polaris-Metadata-Transitive- 為前綴的 HTTP 請求頭即可,例如:X-Polaris-Metadata-Transitive-featureenv=f1。這樣 featureenv=f1 就能夠作為請求標簽在鏈路上透傳。
方式三:網關流量染色
網關常常作為流量的入口或者中轉站。經過網關的請求,可以根據某些染色規則為請求增加標簽信息。例如滿足請求參數 uid=1000 請求打上 featureenv=f1 標簽。
網關流量染色是非常實用的能力,在 Spring Cloud Tencent 里實現了非常靈活基于染色規則的 Spring Cloud Gateway 染色插件。例如以下染色規則可以實現為 uid=1000 的請求打上 featureenv=f1 標簽、uid=1001 的請求打上 featureenv=f2 標簽。更詳細的染色規則,可以參考文檔。
{ "rules":[ { "conditions":[ { "key":"${http.query.uid}", "values":["1000"], "operation":"EQUALS" } ], "labels":[ { "key":"featureenv", "value":"f1" } ] }, { "conditions":[ { "key":"${http.query.uid}", "values":["1001"], "operation":"EQUALS" } ], "labels":[ { "key":"featureenv", "value":"f2" } ] } ] }
同時 Spring Cloud Tencent 也預留了 TrafficStainer SPI ,用戶可以實現自定義流量染色插件。
2.4 Spring Cloud Tencent 路由功能原理
北極星提供了非常完善的服務治理能力,上層的服務框架基于北極星原生 SDK 就能快速實現強大的服務治理能力。Spring Cloud Tencent 就是在北極星的基礎上實現了服務路由能力。
北極星服務路由原理
北極星服務路由實現原理并不復雜,如下圖所示,從注冊中心獲取到所有實例信息,再經過一系列的 RouterFilter 插件過濾出滿足條件的實例集合。
圖:北極星服務路由執行鏈
在多測試環境場景下主要用到了 MetadataRouter (元數據路由)插件,此插件核心能力是根據請求的標簽完全匹配服務實例的標簽。
例如請求有兩個標簽 key1=value1和 key2=value2,MetadataRouter 則會篩選出所有實例中包含同時滿足 key1=value1 和 key2=value2 的服務實例。在多測試環境場景下,Spring Cloud Tencent 缺省使用 featureenv 標簽,通過 featureenv 標簽篩選出屬于同一個測試環境的服務實例。
Spring Cloud Tencent 服務路由原理
Spring Cloud Tencent 實現路由核心分成兩個部分:
擴展 RestTemplate 、 Feign、SCG 獲取請求的標簽信息并塞到 RouterContext (路由信息上下文)里。
擴展 Spring Cloud 負載均衡組件(Hoxton 版本之前為 Ribbon,2020版本之后為 Spring Cloud LoadBalancer),在擴展的實現里調用北極星的服務路由 API 實現服務實例過濾。
擴展部分邏輯較為復雜,感興趣的讀者可以參考 spring-cloud-starter-tencent-polaris-router 模塊源碼。
三、測試環境路由用戶操作指引
在上一節中詳細介紹了測試環境路由的實現原理,這一節則詳細介紹站在用戶的視角需要操作的內容。
通過 Spring Cloud Tencent 實現流量的測試環境路由非常簡單,核心包含三步:
服務增加測試環境路由插件依賴
部署的實例打上環境標簽
為請求流量打上環境標簽
完成以上三個步驟即可。
3.1 添加測試環境路由插件依賴
Spring Cloud Tencent 中的 spring-cloud-tencent-featureenv-plugin 模塊閉環了測試環境路由全部能力,所有服務只需要添加該依賴即可引入測試環境路由能力。
3.2 服務實例打上環境標簽
spring-cloud-tencent-featureenv-plugin 默認以 featureenv 標簽作為匹配標簽,用戶也可以通過系統內置的 system-feature-env-router-label=custom_feature_env_key 標簽來指定測試環境路由使用的標簽鍵。以下三種方式以默認的 featureenv 作為示例。
方式一:配置文件
在服務實例的配置文件中添加配置,如在 bootstrap.yml添加如下所示即可:
spring: cloud: tencent: metadata: content: featureenv:f1#f1替換為測試環境名稱
方式二:環境變量
在服務實例所在的操作系統中添加環境變量也可進行打標,例如:SCT_METADATA_CONTENT_featureenv=f1
方式三:SPI 方式
自定義實現 InstanceMetadataProvider#getMetadata() 方法的返回值里里包含 featureenv 即可。
基線環境標簽值
注意,基線環境部署的服務實例不需要設置 featureenv 標簽,表明其不屬于任何測試環境,才可在請求沒有匹配到對應測試環境的時候,匹配到基線環境。
3.3 流量染色
方式一:客戶端染色 (推薦)
如下圖所示,在客戶端發出的 HTTP 請求里,新增 X-Polaris-Metadata-Transitive-featureenv=f1 請求頭即可實現染色。該方式是讓開發者在請求創建的時候根據業務邏輯進行流量染色。
圖:客戶端染色示意圖
方式二:網關動態染色(推薦)
動態染色是開發者配置一定的染色規則,讓流量經過網關時自動染色,使用起來相當方便。例如把 uid=1 用戶的請求都轉發到 f1 環境,把 uid=0 用戶的請求都轉發到 f2 環境。只需要配置一條染色規則即可實現。
圖:網關動態染色示意圖
Spring Cloud Tencent 通過實現 Spring Cloud Gateway 的 GlobalFilter 來實現流量染色插件,開發者只需要添加 spring-cloud-tencent-gateway-plugin 依賴,并在配置文件中打開染色插件開關(spring.cloud.tencent.plugin.scg.staining.enabled=true)即可引入流量染色能力。
方式三:網關靜態染色
往請求中加入固定的 Header 是網關最常見的插件,如下圖所示。可以在每個環境部署一個網關,所有經過網關的請求都增加 X-Polaris-Metadata-Transitive-featureenv=f1 請求頭即可。此種方式需要每個環境部署網關,成本高,所以使用頻率相對較低。
圖:網關靜態染色示意圖
完成以上操作步驟即可實現測試環境路由,讀者可運行 Spring Cloud Tencent 下 polaris-router-featureenv-example 完整體驗。
四、總結
測試環境路由在微服務架構系統的開發階段是非常實用的功能,能夠大大降低測試環境的維護成本、資源成本,同時能夠極大的提高研發效率。通過操作指引的章節可以看出通過 Spring Cloud Tencent 實現測試環境路由非常簡單的,只需要部署的服務實例增加相應的環境標簽以及在請求頭中增加一個標簽即可。
業界常見的測試環境路由實現方案往往需要下發路由規則給鏈路上的服務,從而實現路由能力。但是通過北極星的元數據路由能力,整個方案里無需下發任何路由規則,只需要在實例設置相應的標簽信息即可,操作成本非常低。
如果項目剛好使用 Spring Cloud Gateway 作為網關,那么集成 Spring Cloud Tencent 里的網關染色插件能夠進一步降低流量染色成本,客戶端無需做任何事情,只需要配置網關染色規則即可實現流量染色。
目前 Spring Cloud Tencent 主要實現了微服務之間調用流量的測試環境路由能力,不涉及消息隊列、任務調度的測試環境路由能力。
五、歡迎共建
如果您所在項目正在使用 Spring Cloud 框架,并且
沉淀出了非常實用的通用插件能力和場景化解決方案
目前正遇到一些落地難題
對 Spring Cloud Tencent 項目感興趣
非常歡迎您跟我們一起打磨更多實用且通用的能力,共建滿足各類實際生產場景使用的微服務開發框架。您的一個建議、Issue、Pull Request 甚至只是一個小小的 Star 都是對 Spring Cloud Tencent 社區極大的支持。
Github 地址:https://github.com/Tencent/spring-cloud-tencent
-
路由
+關注
關注
0文章
279瀏覽量
42339 -
spring
+關注
關注
0文章
340瀏覽量
14878 -
Cloud
+關注
關注
0文章
73瀏覽量
5566
原文標題:如何解決Spring Cloud下測試環境路由問題
文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
如何用ACM簡化你的Spring Cloud微服務環境配置管理
EDAS再升級!全面支持Spring Cloud應用
使用阿里云ACM簡化你的Spring Cloud微服務環境配置管理
Dubbo Cloud Native 之路的實踐與思考
Spring Cloud Function基于Spring Boot的函數計算框架

RabbitRpc基于spring cloud的微服務rpc調用

Spring Cloud Gateway服務網關的部署與使用詳細教程
Spring Cloud Tencent發布最新匹配版本!
Spring Cloud 2022.0.0正式發布
【Spring Cloud 】基于微服務架構的智慧工地監管平臺源碼帶APP

Spring Cloud :打造可擴展的微服務網關

dubbo和spring cloud區別
Spring Cloud Gateway網關框架

評論