🏆【Alibaba中間件技術系列】「Nacos技術專題」服務註冊與發現相關的原理分析

背景介紹

前幾篇文章介紹了Nacos配置中心服務的能力機制,接下來,我們來介紹Nacos另一個非常重要的特性就是服務註冊與發現,說到服務的註冊與發現相信大家應該都不陌生,在微服務盛行的今天,服務是非常重要的,而在 Nacos 中服務更被稱為他的一等公民。Nacos 支援幾乎所有主流類型的 「服務」 的發現、配置和管理。

服務 (Service)

服務是指一個或一組軟體功能(例如特定資訊的檢索或一組操作的執行),其目的是不同的客戶端可以為不同的目的重用(例如通過跨進程的網路調用)。Nacos 支援主流的服務生態,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service。

nacos的架構圖所示

(dubbo) RPC微服務的基礎架構

圖中的6個步驟的含義解釋如下:

  1. 服務容器負責啟動,載入,運行服務提供者。
  2. 服務提供者在啟動時,向註冊中心註冊自己提供的服務。
  3. 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。
  4. 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
  5. 服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
  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