為什么要做 Spring Cloud Tencent
Spring Boot + Spring Cloud 仍是 Java 生態(tài)最主流的框架
2014 年 4 月 Spring Boot 發(fā)布 1.0 版本,經(jīng)過 8 年時間的發(fā)展,Spring Boot 已然成為 Java 開發(fā)框架的事實標(biāo)準(zhǔn)。在分布式微服務(wù)領(lǐng)域,2016 年 1 月 Spring Cloud 發(fā)布 Angel.SR5 版本。Spring Cloud 延承了 Spring Boot 最核心的組件化、低配置快速集成的核心思想,同時定義了一套標(biāo)準(zhǔn)的微服務(wù) SPI?;谶@套 SPI 出現(xiàn)了 Spring Cloud Netfix 等優(yōu)秀的微服務(wù)解決方案實現(xiàn)套件。在遠程服務(wù)調(diào)用框架方面,F(xiàn)eign 和 RestTemplate 基于普適的 HTTP 協(xié)議,在易用性、可觀測性、跨語言等方面具備天然的優(yōu)勢。所以 Spring Cloud 自 2016 年發(fā)布第一個版本之后蓬勃發(fā)展。
從行業(yè)情況看,Spring Boot + Spring Cloud 是目前 Java 使用最廣泛的開發(fā)框架之一。
2018 年開始以 Istio 為代表的 ServiceMesh 開始在社區(qū)中孵化,到 2022 年已經(jīng)有非常多的 ServiceMesh 產(chǎn)品。ServiceMesh 核心思想是下沉服務(wù)調(diào)用相關(guān)的基礎(chǔ)能力到獨立的 Sidecar 進程,通過流量代理的方式治理流量。任何一種方案都不是萬能藥, Sidecar 模式也存在一些問題。例如:高度依賴底層 Paas 能力治理 Sidecar (注入、版本管理、升級等)、Sidecar 需要額外占用一定的資源、增加一定的網(wǎng)絡(luò)延遲、增加排障難度等。所以國內(nèi)真正能夠落地 ServiceMesh 的企業(yè)并不多。
綜上所述,我們認為在未來很長一段時間內(nèi) Spring Boot + Spring Cloud 仍是 Java 主流的微服務(wù)解決方案,雖然它看上去沒有像 Istio、Dapr 那樣的先進。在滿足企業(yè)業(yè)務(wù)發(fā)展訴求的前提下,低成本、高效、穩(wěn)定的架構(gòu)方案才是最好的方案。
騰訊 2021 年開源的北極星(PolarisMesh)提供了一站式微服務(wù)解決方案
北極星是一款集注冊中心、配置中心、服務(wù)治理中心為一體的一站式微服務(wù)解決方案,在騰訊內(nèi)部已覆蓋 90% 的業(yè)務(wù),注冊的實例節(jié)點數(shù)更是達到了 500 萬的規(guī)模。在 21 年開源之后,在社區(qū)內(nèi)也有外部公司生產(chǎn)落地。
公司內(nèi)部的架構(gòu)師經(jīng)常會做一些技術(shù)選型,比如注冊中心用 Zookeeper、Consul、Nacos 等,配置中心用 Apollo、Nacos,限流熔斷用 Sentinel 。多組件也意味著需要維護多套服務(wù),占用更多的資源,用戶體驗上也難以做到一致性。
所以一站式微服務(wù)解決方案能夠大大簡化技術(shù)選型、運維、資源成本。當(dāng)然也可以把北極星當(dāng)做方案里的一部分,例如只用北極星的服務(wù)注冊發(fā)現(xiàn),配置中心仍然選型 Apollo。畢竟還是那個道理,沒有萬能的方案,適合企業(yè)業(yè)務(wù)自身訴求的方案才是最好的方案。
另外北極星在某些能力橫向?qū)Ρ壬弦灿幸欢ǖ膬?yōu)勢。例如完全無狀態(tài)的注冊中心更加便于運維,強大的服務(wù)路由能力支持復(fù)雜的業(yè)務(wù)場景等。具體的產(chǎn)品功能在第二部分會更加詳細的介紹。
小結(jié)
基于以上兩點核心原因,把北極星作為 Spring Cloud 一個開箱即用的實現(xiàn)套件就順理成章了。既能滿足 Spring Cloud 的用戶,又能滿足北極星 Java 的用戶。當(dāng)然 Spring Cloud Tencent 目前只對接了北極星的能力,后續(xù)會支持更多騰訊開源的優(yōu)秀產(chǎn)品。
二、Spring Cloud Tencent 模塊詳細介紹
目前 Spring Cloud Tencent 主要提供了微服務(wù)領(lǐng)域常見的服務(wù)注冊與發(fā)現(xiàn)、配置中心、服務(wù)路由、限流熔斷以及元數(shù)據(jù)鏈路透傳能力。接下去會詳細介紹每一部分的能力。
(圖:Spring Cloud Tencent 能力大圖)
2.1 服務(wù)注冊與發(fā)現(xiàn) (Spring Cloud Tencent Polaris Discovery)
服務(wù)注冊與發(fā)現(xiàn)是 Spring Cloud Tencent 最為核心的功能之一,通過實現(xiàn) Spring Cloud 的服務(wù)注冊與發(fā)現(xiàn)的標(biāo)準(zhǔn)接口,提供微服務(wù)應(yīng)用快速接入北極星服務(wù)注冊中心的能力。開發(fā)者通過簡單的引入 Spring Cloud Tencent 服務(wù)注冊與發(fā)現(xiàn)的依賴,即可使用北極星的服務(wù)注冊與發(fā)現(xiàn)功能。接入服務(wù)注冊與發(fā)現(xiàn)之后,還能按需使用北極星提供的強大服務(wù)治理能力,例如場景化的服務(wù)路由能力、服務(wù)熔斷能力等。方便開發(fā)者針對微服務(wù)的實際生產(chǎn)場景作出個性化的服務(wù)治理配置。
北極星的服務(wù)模型包括命名空間、服務(wù)和服務(wù)實例。
命名空間
命名空間提供了一種在同一個注冊中心下資源的邏輯隔離的機制,同一命名空間下的服務(wù)命名必須唯一,但是跨命名空間允許存在同名的服務(wù)。命名空間常用于區(qū)分不同的環(huán)境或者多個業(yè)務(wù)之間的服務(wù)隔離。
服務(wù)
服務(wù)也是邏輯的概念,提供一個特定業(yè)務(wù)領(lǐng)域的服務(wù)能力。例如訂單服務(wù),用戶服務(wù),轉(zhuǎn)賬服務(wù)等。
服務(wù)實例
服務(wù)實例是服務(wù)下的一個具體的物理節(jié)點。
(圖:服務(wù)實例詳情)
Spring Cloud Tencent 在基礎(chǔ)的服務(wù)注冊發(fā)現(xiàn)上,提供了一些拓展能力。首先,Spring Cloud Tencent 集成了北極星的一些路由插件,通過在北極星控制臺頁面更改服務(wù)實例的隔離狀態(tài)或者權(quán)重值,都可以實現(xiàn)服務(wù)實例的動態(tài)上下線的特性,如上圖所示。
Spring Cloud Tencent 還提供了多服務(wù)注冊與發(fā)現(xiàn)的進階功能。舉個例子,公司內(nèi)部多個部門或組織使用了不同的服務(wù)注冊中心,當(dāng)決策技術(shù)棧統(tǒng)一或是遷移到北極星注冊中心時,需要使用平滑的方式進行業(yè)務(wù)改造,而非直接替換原有的 SDK 接入北極星注冊中心。此時可以使用 Spring Cloud Tencent 的多服務(wù)注冊與發(fā)現(xiàn)的能力,幫助開發(fā)者的微服務(wù)應(yīng)用過渡技術(shù)棧轉(zhuǎn)換的尷尬期。
Spring Cloud Tencent 提供的這樣一系列針對服務(wù)注冊與發(fā)現(xiàn)的周邊功能,完善了微服務(wù)架構(gòu)的治理與管控能力。
2.2 配置中心 (Spring Cloud Tencent Polaris Config)
今年上半年北極星開始支持配置中心的能力。北極星配置中心核心配置三元組模型為:
Namespace
用于邏輯隔離集群的能力,例如常用于隔離環(huán)境。
FileGroup
配置文件組,一組配置文件的集合。在 Spring Cloud Tencent 里,我們推薦的最佳實踐是一個應(yīng)用為一個 FileGroup。對于框架類的配置,以框架名作為一個 FileGroup, 例如 dubbo。
File
配置文件,例如 properties 、yml 格式的配置文件。配置文件為最小管理單元,而不是配置文件里的配置項。
[Namespace, FileGroup, File] 唯一定位一份配置文件。我們在設(shè)計模型的時候,參考了業(yè)界主流的配置中心產(chǎn)品,我們認為配置文件、配置文件組的概念,是開發(fā)者廣泛認知且理解成本最低的配置領(lǐng)域模型,例如本地磁盤的文件夾和文件的概念。
配置中心核心能力是配置管理能力以及動態(tài)實時推送能力。在配置管理方面,一個應(yīng)用往往具有非常多的配置文件,如何清晰的管理配置文件是一個非常重要的能力。我們在管控臺設(shè)計 UI 時,開創(chuàng)性的把文件名以 / 作為分隔符樹狀形式展示。如下圖所示,可以按應(yīng)用模塊劃分目錄,通過目錄方式能夠清晰管理一個應(yīng)用下雜亂的配置文件。
(圖:配置文件管理頁面)
另外在 Spring Cloud 集成方面,眾所周知 Spring Boot 會自動加載應(yīng)用 resources 目錄下的 application.yml、application.properties 以及優(yōu)先級更高的 application- a c t i v e P r o f i l e . y m l 文 件 。 在 S p r i n g C l o u d T e n c e n t P o l a r i s C o n f i g 集 成 時 , 我 們 完 全 沿 用 了 這 套 原 生 的 配 置 加 載 機 制 。 也 就 是 S p r i n g C l o u d T e n c e n t P o l a r i s C o n f i g 在 啟 動 時 , 會 自 動 加 載 應(yīng) 用 文 件 組 下 的 a p p l i c a t i o n . y m l 和 a p p l i c a t i o n {activeProfile}.yml 文件到 Spring 容器里。用戶在做遷移時,只需把 resources 目錄下所有的配置文件原封不動的上傳到北極星即可。
2.3 服務(wù)路由 (Spring Cloud Tencent Polaris Router)
在微服務(wù)領(lǐng)域,由于服務(wù)做了細粒度的拆分部署服務(wù)變的非常的輕量靈活。在結(jié)合 k8s 云原生極速彈性能力之后變的更加的強大。但是底層的 Paas 能力只是提供了基礎(chǔ)彈性能力,真正發(fā)揮能力需要依賴上層的流量調(diào)配的能力。
放眼 Spring Cloud 生態(tài),能夠深度整合 Spring Cloud 提供場景化服務(wù)路由能力的組件套件并不多。這里解釋一下場景化,服務(wù)調(diào)用框架根據(jù)一定的規(guī)則實現(xiàn)服務(wù)路由的能力我們稱之為底層原子能力。原子能力是非常通用的能力,但是很多時候并不能直接用于具體的業(yè)務(wù)場景。例如常見的測試環(huán)境分組,就近路由,藍綠發(fā)布等稱之為場景。服務(wù)路由只有做了場景化之后,才能真正做到開箱即用服務(wù)于業(yè)務(wù)。
Spring Cloud Tencent Polaris Router 目前實現(xiàn)了兩種場景化的路由能力以及一種非常靈活的規(guī)則路由的能力。
元數(shù)據(jù)路由
服務(wù)實例都會附屬一組元數(shù)據(jù),例如環(huán)境信息,機房信息等等。元數(shù)據(jù)路由簡單的講就是以元數(shù)據(jù)信息作為路由的依據(jù)進來路由。這樣講還是有些抽象,我們以一個測試環(huán)境例子來解釋一下。
(圖:開發(fā)環(huán)境示意圖)
上圖是非常經(jīng)典的用于解決測試環(huán)境沖突的方案。一次迭代中 SvcA 需要和 SvcD 聯(lián)調(diào),當(dāng)團隊人數(shù)少的時候,可以直接把 stable 環(huán)境部署成開發(fā)分支代碼然后進行聯(lián)調(diào)。但是當(dāng)多個開發(fā)任務(wù)并行的情況下就會出現(xiàn)環(huán)境爭搶的情況。一種解決方式是每個開發(fā)任務(wù)獨立部署一套全鏈路的環(huán)境,這種方式耗時耗力效果還很差。業(yè)界最主流的做法就是上圖所示,每個開發(fā)任務(wù)子環(huán)境只需要部署聯(lián)調(diào)的應(yīng)用即可,鏈路上不在子環(huán)境里的服務(wù)都路由回 stable 穩(wěn)定環(huán)境。
使用 Spring Cloud Tencent 為了達到以上的目的,只需要每個服務(wù)部署的時候,增加以下兩個環(huán)境變量即可實現(xiàn)。
- SCT_METADATA_CONTENT_ENV=dev1
- SCT_METADATA_CONTENT_TRANSITIVE=ENV
Spring Cloud Tencent Polaris Router 組件會自動讀取以上環(huán)境變量,并在每次服務(wù)調(diào)用時優(yōu)先調(diào)用到跟當(dāng)前實例 ENV 值一樣的目標(biāo)實例。
元數(shù)據(jù)路由使用的場景非常廣泛,更多的細節(jié)請查閱 Github Wiki。
規(guī)則路由
元數(shù)據(jù)路由本質(zhì)上是基于服務(wù)實例的元數(shù)據(jù)進行篩選,是為了支持具體特定的場景而內(nèi)置的服務(wù)路由能力。無需下發(fā)任何路由規(guī)則,使用起來非常簡單。
而實際業(yè)務(wù)場景非常復(fù)雜,例如以下幾種典型的業(yè)務(wù)場景:
- 內(nèi)部員工路由到一套生產(chǎn)灰度環(huán)境,外部普通用戶則路由到生產(chǎn)正式環(huán)境
- VIP 客戶路由到一套高保環(huán)境,普通客戶路由到普通環(huán)境
以上兩種業(yè)務(wù)場景,則無法通過元數(shù)據(jù)路由實現(xiàn)。因為涉及到業(yè)務(wù)請求參數(shù),而不是系統(tǒng)維度的環(huán)境變量。規(guī)則路由就是用于滿足復(fù)雜業(yè)務(wù)場景而實現(xiàn)的一套基于規(guī)則的服務(wù)路由實現(xiàn)。
一個典型的規(guī)則如下圖所示:
(圖:路由規(guī)則配置頁面)
上圖表達的含義是:HTTP Query Param 的 uid 參數(shù)值為 100 時,調(diào)用到 ENV=gray 的實例分組。通過路由規(guī)則能夠描述出絕大多數(shù)復(fù)雜的業(yè)務(wù)場景。
為了便于使用, Spring Cloud Tencent 內(nèi)置了一套表達式標(biāo)簽規(guī)則,自動從 HTTP 請求中解析標(biāo)簽值。目前支持的表達式規(guī)則有:
- ${http.query.xxx}
- ${http.header.xxx}
- ${http.cookie.xxx}
- ${http.method}
- ${http.uri}
規(guī)則路由相對比較復(fù)雜,更多的細節(jié)請查閱 Github Wiki。
就近路由
生產(chǎn)環(huán)境服務(wù)為了高可用、容災(zāi)等能力往往需要多機柜、多機房、多地域部署。
(圖:部署模型圖)
如上圖所示,范圍從小到大依次為: Campus < Zone < Region < All 其中 Campus、Zone、Region 在服務(wù)注冊發(fā)現(xiàn)領(lǐng)域模型里統(tǒng)一定義為元數(shù)據(jù),是一種特殊的位置元數(shù)據(jù)(Location Metadata)。
就近路由顧名思義,服務(wù)調(diào)用時按照同 Campus、同 Zone、同 Region 的優(yōu)先級從高到低依次選取目標(biāo)服務(wù)實例。核心是減少服務(wù)調(diào)用因物理距離增加的網(wǎng)絡(luò)耗時。本質(zhì)上,就近路由是一種基于特定一組位置元數(shù)據(jù)的元數(shù)據(jù)路由。
通過 Spring Cloud Tencent 實現(xiàn)就近路由,只需要在服務(wù)實例上打上以下環(huán)境變量即可。
- SCT_METADATA_CAMPUS
- SCT_METADATA_ZONE
- SCT_METADATA_REGION
2.4 服務(wù)限流(Spring Cloud Tencent Polaris Ratelimit)
隨著業(yè)務(wù)發(fā)展的日益壯大,網(wǎng)絡(luò)請求量也越來越多,導(dǎo)致在某些場景下,業(yè)務(wù)應(yīng)用的服務(wù)端會出現(xiàn)爆發(fā)式的流量涌入,因此需要對服務(wù)提供方的給予一些保護手段。通過服務(wù)限流功能,開發(fā)者可以通過控制 QPS 的方式,以避免被瞬時的流量高峰沖垮,從而保障系統(tǒng)的高可用性。服務(wù)限流主要有兩個應(yīng)用場景, 過載保護 和 業(yè)務(wù)防刷 。過載保護是保護業(yè)務(wù)不被突發(fā)流量打垮,業(yè)務(wù)防刷是防止惡意用戶發(fā)送過多流量影響其他正常用戶。Spring Cloud Tencent 內(nèi)置了針對 Spring Web 和 Spring WebFlux 場景的限流 Filter 幫助業(yè)務(wù)快速接入北極星的限流能力。
Spring Cloud Tencent 支持北極星提供的兩種類型的服務(wù)限流能力,即單機限流與分布式限流。
單機限流
單機限流是針對單個被調(diào)實例的級別的限流,流量限額只針對當(dāng)前被調(diào)實例生效,不共享,如下圖所示。單機限流一般適用于保護服務(wù)自身不被打垮,按照每個服務(wù)集群單機的容量來計算配額。
(圖:單機限流示例圖)
單機限流的效果分為 快速失敗 和 勻速排隊 ??焖偈≈傅氖钱?dāng) QPS 到達限流規(guī)則指定的配額時,立刻返回一個限流類型錯誤響應(yīng)給所有超過閾值的請求。而勻速排隊是一種基于漏桶算法實現(xiàn)的削峰填谷限流方式,幫助服務(wù)端能夠在流量洪峰到達時,還能保證一個勻速處理的狀態(tài),讓一部分請求在一段排隊等待時間后還能被處理,而不是直接失敗。關(guān)于勻速排隊的詳細介紹可以參考 Github 官方 Wiki。
分布式限流
分布式限流是針對服務(wù)下所有實例級別的限流,多個服務(wù)實例共享同一個全局流量限額,如下圖所示。分布式限流一般適用于保護第三方服務(wù)或者公共服務(wù)(比如保護數(shù)據(jù)庫);或者是在網(wǎng)關(guān)層進行限流,對通過網(wǎng)關(guān)接入的后端服務(wù)進行保護。
(圖:分布式限流示例圖)
Spring Cloud Tencent 提供了自定義限流規(guī)則能力,開發(fā)者可以根據(jù)自身的業(yè)務(wù)場景定制對應(yīng)的限流規(guī)則。
(圖:限流規(guī)則配置界面)
2.5 服務(wù)熔斷(Spring Cloud Tencent Polaris Circuitbreaker)
在微服務(wù)架構(gòu)的運維場景下,有時候會遇到單點服務(wù)實例故障的情況,如果不能及時剔除,那么仍舊會有請求轉(zhuǎn)發(fā)到故障的服務(wù)實例上。Spring Cloud Tencent 提供了服務(wù)熔斷的能力,通過上報每次服務(wù)間調(diào)用的結(jié)果,判斷被調(diào)方服務(wù)是否出現(xiàn)故障,進而將其屏蔽,并啟動定時任務(wù)對熔斷實例進行探活。在達到恢復(fù)條件后對其進行半開恢復(fù)。在半開恢復(fù)后,釋放少量請求去進行真實業(yè)務(wù)請求探測。并根據(jù)真實業(yè)務(wù)探測結(jié)果去判斷是否完全恢復(fù)。這個功能能有效剔除異常的服務(wù)實例,為服務(wù)治理提供了重要的幫助。
小結(jié)
以上只是簡單介紹了 Spring Cloud Tencent 部分能力,想詳細了解更多的能力請訪問我們 Github 官方主頁。
三、規(guī)劃和愿景
文章開頭提到我們?yōu)槭裁匆?Spring Cloud Tencent。我們堅信在 Java 領(lǐng)域 Spring Cloud 在很長一段時間內(nèi)仍是微服務(wù)的主流方案。我們希望結(jié)合北極星一站式微服務(wù)能力,降低微服務(wù)架構(gòu)門檻,為廣大企業(yè)提供開箱即用的全套微服務(wù)解決方案。從而使企業(yè)更加聚焦自身業(yè)務(wù)的發(fā)展,提高生產(chǎn)力。
一款好用的產(chǎn)品需要經(jīng)受豐富的場景打磨穩(wěn)定性、易用性,以及不斷完善自身的產(chǎn)品力。以下是我們目前想到的一些需要支持和完善的點。當(dāng)然隨著產(chǎn)品的發(fā)展、使用的用戶越來越多,會有更多的訴求,我們會持續(xù)不斷的迭代下去。
(圖:SCT 規(guī)劃)
期待你的加入
- 如果你也是 Spring Cloud 的愛好者
- 如果你的公司正在使用 Spring Cloud 并且有一些好的實踐
- 如果你的公司正在做微服務(wù)技術(shù)選型
- … …
請加入我們,你的一個建議、Issue、Pull Request 甚至只是一個小小的 Star 都是對我們最大的支持,也是我們持續(xù)迭代的動力。
Spring Cloud Tencent Github 地址:
https://github.com/Tencent/spring-cloud-tencent