天天看點

Nacos注冊中心之概要設計

本文已收錄 https://github.com/lkxiaolou/lkxiaolou 歡迎star。

前言

在之前的文章中分析了Nacos配置中心,配置中心的核心是配置的建立、讀取、推送。

注冊中心的核心比配置中心多一個

服務探活

子產品,他倆的相似度非常高,甚至阿裡内部的注冊中心就叫

ConfigServer

Nacos注冊中心打算分成幾個子產品來分析,本文重點在于

概要設計

,基于2.0.0版本。

環境搭建

用Nacos的源碼來搭建源碼閱讀和調試環境,可參考《Nacos配置中心子產品詳解》

Nacos調試環境搭建

部分。

其中 JVM參數可以指定隻啟動Naming子產品,也可以不指定,預設全都啟動。

example子產品下将NamingExample複制一份進行測試。

設計概要

服務發現模型

用戶端視角的服務發現模型(注意:服務端視角的模型定義與用戶端視角有差別)包含以下幾點内容:

  • Service:服務
  • Cluster:叢集
  • Instance:執行個體
代碼注釋:We introduce a 'service --> cluster --> instance' model, in which service stores a list of clusters, which contains a list of instances

他們的關系如下

Nacos注冊中心之概要設計

Service

Nacos注冊中心之概要設計
  • name:服務名
  • protectThreshold:保護門檻值,限制了執行個體被探活摘除的最大比例
  • appName:服務的應用名,暫無實際用處
  • groupName:分組名
  • metadata:中繼資料

Cluster

Nacos注冊中心之概要設計
  • serviceName:所屬服務名
  • name:叢集名
  • healthChecker:服務探活配置,此處僅對服務端主動探活生效,有TCP、HTTP、MySQL、None幾種方式,預設TCP
  • defaultPort:預設端口
  • defaultCheckPort:預設探活端口
  • useIPPort4Check:是否使用port進行探活

Instance

Nacos注冊中心之概要設計
  • instanceId:執行個體id,唯一标志,Nacos提供了

    simple

    snowflake

    兩種算法來生成,預設是

    simple

    ,其生成方式為

    ip#port#clusterName#serviceName

  • ip:執行個體ip
  • port:執行個體port
  • weight:執行個體權重
  • healthy:執行個體健康狀态
  • clusterName:所屬叢集名
  • enabled:是否接收請求,可用于臨時禁用或摘流等場景
  • ephemeral:是否為臨時執行個體,後文會介紹該參數
  • getInstanceHeartBeatInterval:擷取執行個體心跳上報間隔時間,預設5秒,可配置
  • getInstanceHeartBeatTimeOut:擷取心跳逾時時間,15秒,配置
  • getIpDeleteTimeout:擷取ip被删除的逾時時間,預設30秒,可配置
  • getInstanceIdGenerator:擷取id生成器

除了上述的三層模型外,Nacos注冊中心和配置中心有着一樣的namespace設計,與client綁定,可隔離環境,租戶。

接口設計

  • registerInstance:注冊執行個體
  • deregisterInstance:登出執行個體
  • getAllInstances:擷取一個服務的所有執行個體(包括不健康)
  • selectInstances:根據條件擷取一個服務的執行個體
  • selectOneHealthyInstance:根據負載均衡政策擷取服務的一個健康的執行個體
  • subscribe:訂閱服務
  • unsubscribe:取消訂閱服務
  • getServicesOfServer:根據條件分頁擷取所有服務

互動流程

Nacos 2.0 為ephemeral不同的執行個體提供了兩套流程:

  • ephemeral=false,永久執行個體,與server端的互動采用http請求,server節點間資料同步采用了raft協定,健康檢查采用了server端主動探活的機制
  • ephemeral=true,臨時執行個體,與server端的互動采用grpc請求,server節點間資料同步采用了distro協定,健康檢查采用了TCP連接配接的KeepAlive模式

臨時執行個體的互動流程

  • client初始化,與server建立連接配接
    • 隻與其中一台server節點建立長連接配接
  • client 注冊服務,将serviceName+ip+port+clusterName等資料打包發送grpc請求
    • 同時用戶端緩存已注冊過的服務,當client與server連接配接斷開重連時,client重新将這些資料注冊到server端
  • server端接收到client的注冊請求,将注冊資訊存入client對象(用于儲存client的所有資料)中,并觸發ClientChangedEvent、ClientRegisterServiceEvent、InstanceMetadataEvent
    • ClientChangedEvent觸發server節點之間的資料同步(distro協定)
    • ClientRegisterServiceEvent觸發更新publisherIndexes(儲存service => clientId的Map<Service, Set>,即哪些用戶端注冊了這個服務的索引),同時也觸發一個ServiceChangedEvent,該事件負責向監聽該服務的用戶端進行推送
    • InstanceMetadataEvent,進行中繼資料,Nacos在2.0中将中繼資料與基礎資料拆分開,分為不同的處理流程
  • client訂閱服務
    • 根據serviceName、groupName、clusters資訊生成key,建立eventListener,同時向server端發送訂閱請求,并緩存訂閱資訊,用于連接配接斷開重連後再次向server端發送資訊
  • server端接收到client的訂閱請求
    • 将訂閱資訊打包為subscribers,并存入client對象中,觸發ClientSubscribeServiceEvent事件
    • ClientSubscribeServiceEvent事件更新subscriberIndexes(儲存service => clientId的Map<Service, Set>,即哪些用戶端訂閱了這個服務的索引),同時觸發ServiceSubscribedEvent事件
    • ServiceSubscribedEvent事件會延時500ms向該client推送該服務的最新資料
  • 反向的操作如登出、取消訂閱與正向操作類似,不再贅述

最後

本文從總體上分析了Nacos 2.0的模型設計、接口設計以及互動流程,讀完後對Nacos的服務發現有一個整體上的認識。

後續篇幅會從細節入手,如dubbo Nacos擴充、一緻性協定、探活、CMDB擴充等逐一進行分析。

搜尋關注微信公衆号"捉蟲大師",後端技術分享,架構設計、性能優化、源碼閱讀、問題排查、踩坑實踐。

繼續閱讀