PolarisMesh 源碼系列 --Polaris-Go 註冊發現流程

導語

北極星是騰訊開源的一款服務治理平臺,用來解決分佈式和微服務架構中的服務管理、流量管理、配置管理、故障容錯和可觀測性問題。在分佈式和微服務架構的治理領域,目前國內比較流行的還包括 Spring Cloud,Apache Dubbo 等。在 Kubernetes 的技術領域,也有以 Istio 爲代表的 ServiceMesh 技術。本篇 Blog 主要分析北極星的優勢,及其服務註冊發現的技術實現。

我是如何看待這些技術

要做好一個服務治理框架,核心功能和要素至少包括以下幾點:

從功能實現方面來看,不管是 SpringCloud,Apache Dubbo,Istio 還是北極星,基本都實現了這些功能,那它們的實現思路有什麼不同呢?

SpringCloud

SpringCloud 是完全架構在 SpringBoot 基礎上的,是 SpringBoot 開發框架很自然的延伸,因此繼承了 SpringBoot 框架所有的優點,可以非常靈活的集成各類服務註冊發現、服務治理、可觀測組件。例如 SpringCloud 框架自身開發了 Spring-Cloud-Config 和 Spring-Cloud-Sleuth 組件,分別提供了配置和部分可觀測性的能力;在其他能力方面,早期版本主要由 Netflix 提供的 Eureka, Ribbon, Hystrix 等組件提供了服務註冊發現,服務治理的能力; 隨着 Netflix 很多組件生命週期結束, SpringCloud 又通過自定義的 Abstract LoadBalance/Route 接口及實現, 以及集成的 Resilience4J/Sentinel 等熔斷限流組件,繼續爲用戶提供統一的服務註冊發現,服務治理等方面的能力。

SpringCloud 在實際使用過程中, 可能會給人一種沒有一個統一的服務治理模型的錯覺, 這是因爲 SpringCloud 保持了自身的膠水框架的特性和思路, 可以集成和融合各類治理組件,例如熔斷限流就提供了 Hystrix、Resilience4J、Sentinel 等方式。這樣的框架特性,優勢是靈活,可以融合各類框架,劣勢是抽象統一的治理模型比較困難,因此 SpringCloud 並沒有提供一個統一的服務治理控制面,即使是 Spring-Cloud-Admin 的擴展,也更多是基於 SpringBoot Actuator 提供可觀測的管理,並沒有提供服務治理的控制面能力。

ServiceMesh-Sidecar 模式

ServiceMesh 解耦了業務邏輯和服務治理邏輯,它將服務治理能力下沉到基礎設施,在服務的消費者和提供者兩側以獨立進程的方式部署。這種方式提升了整體架構的靈活性,減少對業務的侵入性並很好的解決了多語言支持的複雜性。劣勢是一方面服務通過 sidecar 的調用多了一道 iptables/ipvs 的轉發,降低了一些性能,Sidecar 也增加了少量的資源使用;另一方面是中小團隊很難對框架靈活擴展,雖然 Envoy 提供了 WASM 機制,其自身也能通過 C++ 擴展 Filter,但是不管哪種方式,都需要團隊有一定經驗的人員來完成,中小團隊很難提供這樣的人員保障。

另外,Istio 雖然也能提供基於虛擬機 / 物理機的部署,但是本身還是基於 Kubernetes 設計的,也對 Kubernetes 部署最友好,對於未使用 Kubernetes 的團隊有一定的挑戰。

PolarisMesh

PolarisMesh 從個人的角度看,是融合和兼容了很多技術的解決方案。

一方面,它可以看作是 SpringCloud 服務治理實踐的一種自頂向下的正向思考過程,SpringCloud 是自底向上的一種構建思路,它提供了各類服務發現、服務治理、可觀測組件的集成和融合,但是並沒有提供統一的頂層治理模型 (或者僅提供了一部分);而 Polaris 是先基於下一代架構基金會所制定的服務治理標準,制定和擴展了服務治理的模型,然後基於該模型,分別構建了服務治理的控制面和數據面 (各類語言的 SDK、開發框架、JavaAgent、Kubernetes Controller)。當然,基於該模型,也能很好的對接到 ServiceMesh 的治理方式, 這樣就給未來的發展也留足了空間。

另一方面,PolarisMesh 也通過插件機制,爲框架擴展預留了空間,如果當前的開源 Polaris 不滿足你的需求,可以較靈活的進行擴展。

polaris-go SDK 服務註冊發現技術分析 & 源碼閱讀

本篇 Blog 重點對 Polaris-Go SDK 的服務的註冊和發現做下技術分析, 以及源碼閱讀。主要是服務註冊和發現是各類服務治理框架最基礎和核心的功能,因此先從它開始吧~

公共部分 SDKContext

在客戶端 SDK, 不論是服務註冊的 API, 還是服務發現的 SDK,其內部都是封裝了 SDKContext 的上下文, SDKContext 內部構成如下圖所示:

服務註冊流程

服務註冊的粗略流程如下圖所示 :

go 客戶端 SDK 的整體服務註冊流程比較線性, 沒有涉及特別複雜的邏輯, 相關 gRPC service 如下:

service PolarisGRPC {
  // 客戶端上報
  rpc ReportClient(Client) returns (Response) {}
  // 被調方註冊服務實例
  rpc RegisterInstance(Instance) returns (Response) {}
  // 被調方反註冊服務實例
  rpc DeregisterInstance(Instance) returns (Response) {}
  // 統一發現接口
  rpc Discover(stream DiscoverRequest) returns (stream DiscoverResponse) {}
  // 被調方上報心跳
  rpc Heartbeat(Instance) returns (Response) {}
  // 上報服務契約
  rpc ReportServiceContract(ServiceContract) returns (Response) {}
}

服務發現流程

服務發現流程相對於服務註冊流程要複雜很多, 主要原因是北極星的服務發現會涉及本地 Cache 與 遠程 Server 端信息的懶加載同步,同時加載的服務信息也比較複雜,包括實例信息,服務信息,路由信息,限流信息等內容。

服務發現的粗略流程如下圖所示 :

可以看到,服務發現中的關鍵點包括:

go SDK 服務發現的 gRPC 接口如下:

// DiscoverClient 服務發現客戶端接口
type DiscoverClient interface {
  // Send 發送服務發現請求
  Send(*apiservice.DiscoverRequest) error
  // Recv 接收服務發現應答
  Recv() (*apiservice.DiscoverResponse, error)
  // CloseSend 發送EOF
  CloseSend() error
}

結語

上面的技術分析因爲時間有限,難免有錯誤和遺漏,歡迎大家指正, 也特別感謝社區的幫助。北極星通過對服務治理標準的實現,提供了完善的服務發現和治理方案。同時, SDK 客戶端與 Server 服務端的數據同步與交互,也有設計良好的服務治理模型和健壯的通信機制提供了可靠的保障。此外,通過插件機制,SDK 框架 也提供了靈活擴展的能力 。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Mek8oCiRZEggG0SbeQx9VQ