🏆【Alibaba中間件技術系列】「Nacos技術專題」服務註冊與發現相關的原理分析
- 2022 年 1 月 22 日
- 筆記
- 【技術專區-Alibaba】
背景介紹
前幾篇文章介紹了Nacos配置中心服務的能力機制,接下來,我們來介紹Nacos另一個非常重要的特性就是服務註冊與發現,說到服務的註冊與發現相信大家應該都不陌生,在微服務盛行的今天,服務是非常重要的,而在 Nacos 中服務更被稱為他的一等公民。Nacos 支援幾乎所有主流類型的 「服務」 的發現、配置和管理。
服務 (Service)
服務是指一個或一組軟體功能(例如特定資訊的檢索或一組操作的執行),其目的是不同的客戶端可以為不同的目的重用(例如通過跨進程的網路調用)。Nacos 支援主流的服務生態,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service。
nacos的架構圖所示
(dubbo) RPC微服務的基礎架構
圖中的6個步驟的含義解釋如下:
- 服務容器負責啟動,載入,運行服務提供者。
- 服務提供者在啟動時,向註冊中心註冊自己提供的服務。
- 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。
- 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
- 服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
- 服務消費者和提供者,在記憶體中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
服務註冊中心 (Service Registry)
上圖中Registry就是註冊中心,負責服務的註冊與發現,Dubbo服務體系之前使用Zookeeper或者自己的Registry 實現,而 Nacos 則是另一種 Registry的實現。
服務註冊中心,它是服務,其實例及元數據的資料庫(Dubbo3已經將源數據中心、配置服務全部提取獨立出來了),服務實例在啟動時註冊到服務註冊表,並在關閉時註銷。
服務和路由器的客戶端查詢服務註冊表以查找服務的可用實例,服務註冊中心可能會調用服務實例的健康檢查 API 來驗證它是否能夠處理請求。
服務元數據 (Service Metadata)
服務元數據是指包括服務端點(endpoints)、服務標籤、服務版本號、服務實例權重、路由規則、安全策略等描述服務的數據。
邏輯架構及其組件介紹
- 服務管理:實現服務CRUD,域名CRUD,服務健康狀態檢查,服務權重管理等功能
- 配置管理:實現配置管CRUD,版本管理,灰度管理,監聽管理,推送軌跡,聚合數據等功能
- 元數據管理:提供元數據CURD 和打標能力
- 插件機制:實現三個模組可分可合能力,實現擴展點SPI機制
- 事件機制:實現非同步化事件通知,sdk數據變化非同步通知等邏輯
- 日誌模組:管理日誌分類,日誌級別,日誌可移植性(尤其避免衝突),日誌格式,異常碼+幫助文檔
- 回調機制:sdk通知數據,通過統一的模式回調用戶處理。介面和數據結構需要具備可擴展性
- 定址模式:解決ip,域名,nameserver、廣播等多種定址模式,需要可擴展
- 推送通道:解決server與存儲、server間、server與sdk間推送性能問題
- 容量管理:管理每個租戶,分組下的容量,防止存儲被寫爆,影響服務可用性
- 流量管理:按照租戶,分組等多個維度對請求頻率,長鏈接個數,報文大小,請求流控進行控制
- 快取機制:容災目錄,本地快取,server快取機制。容災目錄使用需要工具
- 啟動模式:按照單機模式,配置模式,服務模式,dns模式,或者all模式,啟動不同的程式+UI
- 一致性協議:解決不同數據,不同一致性要求情況下,不同一致性機制
- 存儲模組:解決數據持久化、非持久化存儲,解決數據分片問題
- Nameserver:解決namespace到clusterid的路由問題,解決用戶環境與nacos物理環境映射問題
- CMDB:解決元數據存儲,與三方cmdb系統對接問題,解決應用,人,資源關係
- Metrics:暴露標準metrics數據,方便與三方監控系統打通
- Trace:暴露標準trace,方便與SLA系統打通,日誌白平化,推送軌跡等能力,並且可以和計量計費系統打通
- 接入管理:相當於阿里雲開通服務,分配身份、容量、許可權過程
- 用戶管理:解決用戶管理,登錄,sso等問題
- 許可權管理:解決身份識別,訪問控制,角色管理等問題
- 審計系統:擴展介面方便與不同公司審計系統打通
- 通知系統:核心數據變更,或者操作,方便通過SMS系統打通,通知到對應人數據變更
- OpenAPI:暴露標準Rest風格HTTP介面,簡單易用,方便多語言集成
- Console:易用控制台,做服務管理、配置管理等操作
- SDK:多語言sdk
- Agent:dns-f類似模式,或者與mesh等方案集成
- CLI:命令行對產品進行輕量化管理,像git一樣好用
Nacos 的服務註冊與發現
服務提供方 (Service Provider)
是指提供可復用和可調用服務的應用方。
模擬服務註冊
服務註冊最重要的就是將服務註冊到哪裡,在註冊中心服務端,肯定有一個用來管理服務的容器,他保存著所有服務的實例。不需要知道該容器具體的實現細節,只需要知道有這樣一個概念。
- 將同一個服務的兩個實例註冊到 Nacos 中:
- 雙註冊模式注入進入
- 維持服務在線狀態
demo程式碼如下:
通過 NamingService 介面的 registerInstance 方法就可以將服務進行註冊了,該方法有很多重載的方法,這裡我們選擇一個簡單的來調用就好了。註冊完成後,通過調用 getAllInstances 方法,立即獲取所有可用的實例,然後讓主執行緒等待,列印如下:
可以發現naming客戶端成功獲取到了兩個實例。
服務消費方 (Service Consumer)
服務註冊到註冊中心後,服務的消費者就可以進行服務發現的流程了,消費者可以直接向註冊中心發送獲取某個服務實例的請求,這種情況下註冊中心將返回所有可用的服務實例給消費者,但是一般不推薦這種情況。另一種方法就是服務的消費者向註冊中心訂閱某個服務,並提交一個監聽器,當註冊中心中服務發生變更時,監聽器會收到通知,這時消費者更新本地的服務實例列表,以保證所有的服務均是可用的。
Nacos消費服務機制
是指會發起對某個服務調用的應用方。服務註冊之後,服務的消費者就可以向註冊中心訂閱自己所需要的服務了,註冊中心會將所有服務的實例「推送」給消費者,實際上獲取服務是客戶端主動輪詢的,跟客戶端獲取配置中心的配置項的原理一樣。
現在我創建一個服務消費者,然後向註冊中心訂閱一個服務,當接收到註冊中心返回的服務列表之後,執行5次 select 服務實例的操作,相當於進行一個模擬的服務請求,具體的程式碼如下圖所示:
其中的 printInstances 方法主要是列印出所有服務的實例,將 ServiceConsumer 類啟動之後,列印出如下的日誌:
Nacos機制負載均衡
負載均衡有很多中實現方式,包括輪詢法,隨機方法法,對請求ip做hash後取模等等,從負載的維度考慮又分為:服務端負載均衡和客戶端負載均衡。Nacos 的客戶端在獲取到服務的完整實例列表後,會在客戶端進行負載均衡演算法來獲取一個可用的實例,模式使用的是隨機獲取的方式。
Nacos 服務註冊與訂閱的完整流程
-
Nacos客戶端進行服務註冊有兩個部分組成,一個是將服務資訊註冊到服務端,另一個是像服務端發送心跳包,這兩個操作都是通過NamingProxy 和服務端進行數據交互的。
-
Nacos客戶端進行服務訂閱時也有兩部分組成,一個是不斷從服務端查詢可用服務實例的定時任務,另一個是不斷從已變服務隊列中取出服務並通知 EventListener 持有者的定時任務,更新服務訂閱列表。
參考資料
//nacos.io/zh-cn/docs/feature-list.html