面向異構技術棧和基礎設施的服務治理標準化

語言: CN / TW / HK

前言

在已落幕的 QCon 全球軟件開發大會·北京站《雲原生微服務架構新趨勢》專場,業界大佬們針對以基礎設施和業務分離為核心目標,多運行時 /Dapr 等概念/項目被提出已有 2 年有餘,它們是否真正解決了我們面臨的問題?業務的反饋如何?是一個明確的新趨勢嗎?另一邊,微服務治理標準化是否可行? Proxyless 是正確的路線嗎? Java 如何適配雲原生微服務架構?等問題進行了熱烈討論。騰訊雲中間件團隊技術專家單家駿針對以上問題也帶來了精彩分享,議題是《面向異構技術棧和基礎設施的服務治理標準化。》

本次分享主要從以下5個小節進行,首先從企業級服務架構入手,介紹異構技術設施和技術棧在現代企業架構所存在的必要性及對服務治理所帶來的挑戰,接下來介紹針對這些挑戰的解決方案--服務治理標準化建設,最後分享標準化方案的生態建議。

背景

企業級服務治理金字塔

本次分享主題和服務治理有關,而服務治理主要是為企業應用服務的,因此我們先看一下企業應用架構的組成。

當我們需要開發一套系統,首先要進行架構選型,架構選型的兩大影響因素是組織架構和業務複雜度。如果組織人員比較少(10人以下)而且業務可能只有1-2個模塊,那麼就可以直接選擇單體集羣架構。如果團隊中人員比較多,而且業務模塊比較複雜,那麼可以使用分佈式或微服務架構,按業務模塊進行服務的劃分,各模塊之間通過分佈式消息調用進行解耦,達到並行開發、數據隔離、故障隔離的目的。

確定了架構形態後,我們需要進行系統開發,開發系統需要選型合適的技術棧,也就是語言和框架。一般來説,業務的匹配度以及開發效率是技術棧選型的影響因素,比如前端一般使用 JS,後台類可能使用 C++,Java,Go 這些;相同的可以開發後端應用的語言,用户往往願意選擇生態更豐富,開發效率更高的語言。

業務實現後,需要解決部署的問題。部署的基礎設施一般有容器化和虛擬機,決定這方面的影響因素往往是成本,包括資源成本和運維成本。另外上雲的話,基於合規以及和雲廠商 argu 的考慮,企業往往也會採用混合雲(比如金融類業務需要部署在金融區),或者多雲方案。

業務部署完成後,我們需要對業務平滑上下線及高質量運營。這時候我們要有對應的灰度策略。同時上線運行後,我們也要有一定的手段控制業務出現故障時的影響範圍,以及對故障進行及時的監控及告警,這時候就需要我們對服務進行治理。只有業務能夠高質量發佈及運營,才能創造商業價值。

影響服務治理的,往往是下面的兩個支撐要素,技術棧和基礎設施。

什麼是多技術棧

技術棧主要涉及的是開發業務所需的語言和框架,從業務的模塊架構來看,最簡單的業務系統,都包含2個模塊,Web 前端以及後端。而對於複雜點的業務,比如像 AI 中台,包含 Web 服務、後台業務(比如用户認證、數據增刪查改)、基礎服務(比如存儲、緩存、日誌等系統),還有AI相關的服務,比如用户分析,智能推送等。每部分模塊都會有最適合的語言和框架,這時候,多技術棧就是解決複雜系統開發效率最好的手段,而且也是企業架構的常態,會長期存在。

什麼是異構基礎設施

首先看基礎設施,先忽略 Serverless 的場景,對新業務以及願意做容器化改造的業務,優選的是容器,因為容器可以獲得更好的資源利用率和部署效率。而對於一些強依賴系統底層的業務,比如音視頻的業務,或者是簡單的單體應用,往往不需要去做容器化,純虛擬機部署就解決。而對於中間這部分容器化的過度階段或者只能部分容器化的業務,則會出現異構基礎設施容器化和虛擬機共存。

對服務治理的挑戰

回過頭來,我們看看異構基礎設施和多技術棧,對服務治理會產生什麼樣的挑戰:

服務發現模型不一致

不同的 PaaS 都有自己的服務模型及服務發現機制,比如 K8s 會基於 etcd+coredns 進行服務定義和集羣內發現,自建的 PaaS 也會有自己定義的服務模型。部署在不同的 PaaS 上的應用需要通信,則需要使用統一的服務模型。業界一般有以下的解決方案:

解決方案 存在問題
使用外置全局 DNS 進行服務發現 DNS 默認會有緩存時延,會導致節點變更不及時。
使用 LB +全局 DNS 進行服務發現 能解決緩存問題,但是由於中間多了一個 LB,所以主調方沒法做負載均衡,長鏈接場景下,會有負載不均的情況。
使用外置註冊中心 不同註冊中心的服務模型也存在差異,如果要互通或者遷移需要做額外的處理。

服務治理規則模型不一致

不同的服務治理套件都有自己的規則,同時服務框架本身也帶有部分治理功能。而不同框架之間的配置,以及功能完整性都會存在差異。比如熔斷,像 hystrix 的熔斷,是當錯誤率出現閾值時候,切斷訪問資源的所有流量。而有些框架,熔斷是彈性的熔斷,就是錯誤率達到閾值後,會減少流量的接入並非全切斷。針對這些問題,業界一般有以下的解決方案:

解決方案 存在問題
業務系統使用統一的服務框架 1.  存量系統,存在較大改造工作量;2.  一套框架可能適合不了所有的業務場景。
使用 Sidecar,將服務治理能力下沉 1.  接管流量存在性能損耗;2.  非 K8S 場景使用運維比較複雜。

解決方案:服務治理標準化

為了解決上面的這些問題,linux 基金會旗下的下一代基金會,聯合各開源社區及企業,共建服務治理標準化,主要包含兩部分:

第一,是建議一套中立通用的服務治理標準,包括功能及接口的定義。

第二,只有定義的話,別人也無法直接使用,因此還需要有一套匹配的標準實現,解決重複開發和功能下沉的問題。

基於這個理念,由北極星社區牽頭設計了一套標準化方案:

關鍵的目標是可以做到與基礎設施和技術棧無關,同時也可以兼容存量系統及接口,用户可無縫接入,平滑遷移。

第一層是治理面,負責服務治理規則的下發,數據管理及全局功能實現。主要分為服務管理、流量管理、故障容錯、訪問控制、可觀測性五部分。

第二層是數據面,數據面是服務治理功能的標準實現,提供多語言 SDK、以及 JavaAgent 這2種不需要額外 Sidecar 的形態,以及提供 Sidecar 的標準實現,支持 Proxy 接入的場景。

第三層是服務框架,是直接面嚮應用的組件,框架可以通過集成數據面組件的方式來快速接入服務治理,也自己按照標準化的定義來進行功能的實現。

接下來我們介紹這幾部分的功能:

服務管理

服務管理包含服務定義及健康檢查兩部分。

首先是服務定義,服務定義基於兩個思路來設計,第一個是最簡和可擴展,第二個是和現有生態能夠無縫互通。所以我們服務模型是基於命名空間-服務-實例這3層的模型,每一層模型通過元數據來保證可擴展性,與現有的 K8S 以及其他註冊中心的服務模型保證兼容及可轉化。

第二是健康檢查,需要支持常見的應用通過心跳等方式維護自身的健康狀態,同時也要支持由第三方的 PaaS 平台進行管理應用的健康狀態。

流量管理

流量管理包含了主調方的出流量管理,以及被調方的入流量管理。比如對於灰度的場景,10%流量發送到灰度分組,那麼首先 SDK 會按百分比的方式對流量進行染色,加上請求標籤,接下來,會通過請求路由根據請求標籤,匹配出灰度分組的實例列表。最後再通過負載均衡算法,篩選出目標實例。而在被調方,則會根據自己的系統容量,對請求進行限流判斷,對於超過 QPS 配額的流量, 可以進行拒絕或者排隊。

故障容錯

接下來是故障容錯,故障容錯包含針對故障發生時的重試機制,以及故障達到閾值後的熔斷機制。

重試是個很重要的能力,所有的重試都是在系統處理請求出錯後進行的,沒有處理好的重試會有放大系統故障的風險。所以,SPEC 中約定了兩個關鍵的重試要素:第一個需要解決的是應該重製的請求,該如何重試。比如對於鏈路層的錯誤,是應該重製的,重試加上退避策略使得重試更有效果,一般會有指數級時延退避,隨機退避等策略。第二個需要解決的是不應該重試的請求,如何進行抑制。比如説,對於單點實例的重試,是要避免的,每次重試應該重試到不同的實例。還有就是對於鏈路級的重試,要做到只在出現故障的服務進行重試,上游不需要重試。

故障後除了重試,我們也需要熔斷,熔斷也會有2種場景,一種是針對硬件出現故障或者新上線的應用部分接口出現BUG的情況,這種場景需要主調方對所調用的資源的流量全熔斷一段時間再嘗試恢復。第二種情況並不是出現故障,而是出現過載了,這樣的話,最合理的熔斷方式是部分熔斷,維持在剛好不過載的水位,對額外的低優先級請求進行丟棄。

訪問控制

最後我們講一下訪問控制,對於一些安全性較高的業務,比如金融類業務,需要解決服務資源的訪問安全問題。主要包括對身份的認證,以及確認身份後對其訪問的資源進行鑑權。

首先要保證每個來訪者都是合法的,需要對來源請求進行身份認證,認證通過後才接納。

來訪者是合法的,但不保證他有權限訪問到他需要的資源,因此管理員需要對資源進行授權,同時對請求訪問的資源進行權限校驗,確保不會出現訪問越權。

默認實現 --- PolarisMesh

剛剛介紹的都是功能怎麼做的一個規範,但是為減少用户的接入成本,我們還需要一個默認實現。下面我們介紹下標準化的默認實現--北極星(http://github.com/polarismesh)。

PolarisMesh(北極星)是騰訊開源的生產級的服務治理組件,一體化的治理平面提供了服務管理、流量管理、故障容錯和配置管理的功能,基於標準化的接口定義,下發治理規則與服務配置數據到數據平面。而數據平面則提供服務治理的功能實現,同時也支持 SDK, Java Agent,Sidecar 等多種接入方式,可以在虛擬機、容器等任意的環境,實現服務數據的互通,大家都共享同一份治理配置和實現,無需做額外的重複開發。

看到這裏可能大家就會問,業界已經有 XDS 了,而且 XDS 本身可以實現控制面於數據面之間的服務治理協議的交互,為啥不直接用 XDS 呢,這裏之前也考慮過,但是基於實踐上遇到了的一些問題最終還是放棄,這裏初步列舉了一些原因和對比,主要是以下這幾點差異性。儘管存在差異,北極星的服務治理定義,可以和 XDS 兼容,同樣可以支持 XDS 的客户端(比如Envoy、Grpc-xds)的接入。

Xds Specification Polaris Specification
概念模型 當前 XDS 主要還是源於 Envoy 的數據模型,治理協議分散在 LDS、 CDS、RDS、EDS 中,與網關的技術模型比較貼近,存在一定理解成本。 以服務為中心的治理模型、所有的流量管理、故障容錯、鑑權都圍繞服務進行,按功能和場景維度來劃分模型。
功能對比 XDS 當前只覆蓋了服務治理的基本功能,在一些細節功能以及場景化的覆蓋上還存在不足,比如支持主調規則、分佈式限流的策略等。 提供了更具體的服務治理基礎能力和標準實現,未來會場景化進行進一步封裝(比如多環境路由、灰度等)。
性能優化 XDS 默認標準實現是基於全量和增量下發規則,在規則較大的情況下,存在啟動緩慢問題。 默認支持按需下發規則,規則的下發只會在首次使用功能時候進行。
標準實現 默認只提供 Envoy 的標準全功能數據面實現,對非 Sidecar 場景支持不夠友好 提供多語言 SDK,Sidecar、JavaAgent 等多種數據面實現。
兼容性 - 提供 XDS 的適配能力,支持使用 XDS 的數據面組件也接入。

生態建設

服務治理標準化需要先與框架生態進行融合,才能更好的提供能力供應用開發者使用。

北極星與業界多個主流框架生態進行了擴展整合,確保開發者可以無需修改或者少量應用代碼即可接入標準化的服務治理能力。

當前已實現對接服務框架如下:

框架 已對接功能 Github地址
Spring Cloud 服務發現、配置管理、熔斷降級、流量管理、可觀測性 http://github.com/Tencent/spring-cloud-tencent
cloudwego/kitex 註冊發現、熔斷降級、流量管理 http://github.com/kitex-contrib/polaris
kratos 註冊發現、配置管理、流量管理 http://github.com/go-kratos/kratos/tree/main/contrib/polaris
dubbogo 服務發現、熔斷降級、流量管理 http://github.com/apache/dubbo-go/tree/master/filter/polaris/limithttp://github.com/apache/dubbo-go/tree/master/cluster/router/polarishttp://github.com/apache/dubbo-go/tree/master/registry/polaris

未來規劃

服務治理標準化建設,未來會從兩個方向進行進一步的迭代和完善:

標準化規則的建設上:

會進一步完善當前提供的服務治理能力,如可觀測性,同時為更好的解決用户實際場景化的問題,則需要多個原子化功能組裝使用,比如灰度發佈需要組合使用染色、路由、可觀測性等能力,存在一定使用成本。未來會封裝場景化的規則,通過場景化規則自動聯動多個原子能力工作,降低使用成本。

生態建設上:

會進一步提供對多語言的支持(比如 Nodejs/.net 等)。同時加強與框架社區合作,在繼續完善當前已對接的生態組件的基礎上,支持更多主流的框架生態的對接。

寫在最後

服務治理標準化協議已經發布了1.0.0版本,歡迎大家提出寶貴意見,並可基於北極星及對接的生態組件進行體驗:

Specification:http://github.com/nextarch/SIG-Microservice

PolarisMesh:http://github.com/polarismesh

Spring Cloud生態:http://github.com/Tencent/spring-cloud-tencent

cloudwego/kitex生態:http://github.com/kitex-contrib/polaris

kratos生態:http://github.com/go-kratos/kratos/tree/main/contrib/polaris

dubbo/dubbogo生態:

http://github.com/apache/dubbo-go/tree/master/filter/polaris/limit

http://github.com/apache/dubbo-go/tree/master/cluster/router/polaris

http://github.com/apache/dubbo-go/tree/master/registry/polaris

http://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-registry-extensions/dubbo-registry-polaris

http://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-cluster-extensions/dubbo-cluster-polaris-dubbo2

http://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-filter-extensions/dubbo-filter-polaris-dubbo2

歡迎加入交流羣一起共建: