三、Dubbo 注冊中心
3.1 注冊中心概述
- 主要作用
- 動態加入:服務提供者通過注冊中心動態地把自己暴露給其他消費者
- 動態發現:消費者動態地感知新的配置、路由規則和新的服務提供者
- 動態調整:注冊中心支持參數的動態調整,新參數自動更新到所有相關服務節點
- 統一配置:避免本地配置導致每個服務的配置不一致問題
- 工作流程
- 服務提供者啟動時,會向注冊中心寫入自己的元數據信息,同時會訂閱配置元數據信息
- 消費者啟動時,也會向注冊中心寫入自己的元數據信息,并訂閱服務提供者、路由和配置元數據信息
- 服務治理中心(dubbo-admin)啟動時,會同時訂閱所有消費者、服務提供者、路由和配置元數據信息
- 當有服務提供者離開或有新的服務提供者加入時,注冊中心服務提供者目錄會發生變化,變化信息會動態通知給消費者、服務治理中心
- 當消費方發起服務調用時,會異步將調用、統計信息等上報給監控中心(dubbo-monitor?simple)
- 數據結構
- 不同的注冊中心有不同的實現方式。其數據結構也不相同、
- ZooKeeper 原理概述
- 樹形結構的注冊中心,每個節點類型分為持久節點、持久順序節點、臨時節點和臨時順序節點。Dubbo使用ZooKeeper作為注冊中心時,只會創建持久節點和臨時節點兩種
- 持久節點:服務注冊后保證節點不會丟失,注冊中心重啟也會存在
- 持久順序節點:在持久節點特性的基礎上增加了節點先后順序的能力
- 臨時節點:服務注冊后連接丟失或session超時,注冊的節點會自動被移除
- 臨時順序節點:在臨時節點特性的基礎上增加了節點先后順序的能力
- 樹形結構的關系:
- 樹的根節點是注冊中心分組,下面有多個服務接口,分組值來自用戶配置dubbo:registry中的 group 屬性,默認是/dubbo
- 服務接口下包含4類子目錄,分別是providers、consumers、routers、configurators,這個路徑是持久節點
- 服務提供者目錄(/dubbo/service/providers) 包含的接口有多個服務者URL元數據信息
- 服務消費者目錄(/dubbo/service/consumers) 包含的接口有多個消費者URL元數據信息
- 路由配置目錄(/dubbo/service/routers)下面包含多個用于消費者路由策略元數據信息
- 動態配置目錄(/dubbo/service/configurators)下面包含多個用于服務者動態配置URL元數據信息
3.2 訂閱/發布
- 樹形結構的注冊中心,每個節點類型分為持久節點、持久順序節點、臨時節點和臨時順序節點。Dubbo使用ZooKeeper作為注冊中心時,只會創建持久節點和臨時節點兩種
- ZooKeeper 的實現
- 發布的實現
- 服務提供者和消費者都需要把自己注冊到注冊中心。服務提供者的注冊是為了讓消費者感知服務的存在,從而發起遠程調用;也讓服務治理中心感知有新的服務提供者上線
- 訂閱的實現
- 訂閱通常有pull和push兩種方式,一種是客戶端定時輪詢注冊中心拉取配置,另一種是注冊中心主動推送數據給客戶端。目前Dubbo采用的是第一次啟動拉取方式,后續接收事件重新拉取數據
3.3 緩存機制
- 訂閱通常有pull和push兩種方式,一種是客戶端定時輪詢注冊中心拉取配置,另一種是注冊中心主動推送數據給客戶端。目前Dubbo采用的是第一次啟動拉取方式,后續接收事件重新拉取數據
- 發布的實現
- 消費者或服務治理中心獲取注冊信息后會做本地緩存。內存中會有一份,保存在Properties對象里,磁盤上也會持久化一份文件,通過file對象引用
- 緩存的加載
- 在服務初始化的時候,AbstractRegistry構造函數里會從本地磁盤文件中把持久化的注冊數據讀到Properties對象里,并加載到內存緩存中
- 緩存的保存與更新
- 緩存的保存有同步和異步兩種方式。異步會使用線程池異步保存,如果線程在執行過程中出現異常,則會再次調用線程池不斷重試
3.4 重試機制
- 緩存的保存有同步和異步兩種方式。異步會使用線程池異步保存,如果線程在執行過程中出現異常,則會再次調用線程池不斷重試
- FailbackRegistry 繼承了AbstractRegistry,并在此基礎上增加了失敗重試機制作為抽象能力
- FailbackRegistry抽象類中定義了一個ScheduledExecutorService,每經過固定間隔(默認為5秒)調用FailbackRegistry#retry()方法
3.5 設計模式 - 模板模式
-
整個注冊中心的邏輯部分使用了模板模式
-
- AbstractRegistry實現了 Registry接口中的注冊、訂閱、查詢、通知等方法,還實現了磁盤文件持久化注冊信息這一通用方法。但是注冊、訂閱、查詢、通知等方法只是簡單地把URL加入對應的集合,沒有具體的注冊或訂閱邏輯
-
FailbackRegistry又繼承了 AbstractRegistry,重寫了父類的注冊、訂閱、查詢和通知等方法,并且添加了重試機制。此外,還添加了四個未實現的抽象模板方法
-
- 工廠模式
-
所有的注冊中心實現,都是通過對應的工廠創建
-
-
AbstractRegistryFactory 實現了 RegistryFactory 接口的 getRegistry(URL url)方法,是一個通用實現,主要完成了加鎖,以及調用抽象模板方法createRegistry(URL url)創建具體實現等操作,并緩存在內存中
-
每種注冊中心都有自己具體的工廠類,在RegistryFactory接口中判斷
-