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 內部構成如下圖所示:
-
ConfigurationImpl: 主要是客戶端 polaris.yaml 配置文件的映射, 分爲 4 個部分,分別是 GlobalConfig, ConsumerConfig, ProviderConfig 和 ConfigFileConfig 。
-
ConnectionManager: gRPC 連接的連接池管理接口。
-
plugin.Manager: 插件管理接口,SDK 內部實現的各類功能 - 熔斷,限流,配置,健康檢查,路由,負載均衡等都是按照插件的方式實現, 插件需要實現 Plugin 接口,通過 PluginProxy 包裝後交給 plugin.Manager 管理。
-
Engine:SDK 執行的各類動作,都交由 Engine 處理, 例如服務的註冊發現,限流,路由,熔斷等,都是調用 Engine 內的 API 實現。也就是 SDK 能執行的功能,都是由 Engine API 統一實現。
服務註冊流程
服務註冊的粗略流程如下圖所示 :
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 端信息的懶加載同步,同時加載的服務信息也比較複雜,包括實例信息,服務信息,路由信息,限流信息等內容。
服務發現的粗略流程如下圖所示 :
可以看到,服務發現中的關鍵點包括:
-
SDK 內部實現了 LocalCache 緩存機制, 同時 LocalCache 緩存具備以懶加載方式同步遠程 Server 中服務信息的能力。
-
SDK 與遠程服務信息的同步,是由插件 Serverconnector 實現, SDK 客戶端通過專門的 Routine 和 Channel 隊列,在服務信息第一次遠程懶加載完成後, 定時拉取遠程 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