前言
在之前的文章中分析了Nacos配置中心骡湖,配置中心的核心是配置的創(chuàng)建榛臼、讀取、推送恩静。
注冊中心的核心比配置中心多一個服務(wù)探活
模塊焕毫,他倆的相似度非常高,甚至阿里內(nèi)部的注冊中心就叫ConfigServer
驶乾。
Nacos注冊中心打算分成幾個模塊來分析邑飒,本文重點(diǎn)在于概要設(shè)計(jì)
,基于2.0.0版本级乐。
環(huán)境搭建
用Nacos的源碼來搭建源碼閱讀和調(diào)試環(huán)境疙咸,可參考《Nacos配置中心模塊詳解》 Nacos調(diào)試環(huán)境搭建
部分。
其中 JVM參數(shù)可以指定只啟動Naming模塊风科,也可以不指定撒轮,默認(rèn)全都啟動。
example模塊下將NamingExample復(fù)制一份進(jìn)行測試贼穆。
設(shè)計(jì)概要
服務(wù)發(fā)現(xiàn)模型
客戶端視角的服務(wù)發(fā)現(xiàn)模型(注意:服務(wù)端視角的模型定義與客戶端視角有區(qū)別)包含以下幾點(diǎn)內(nèi)容:
- Service:服務(wù)
- Cluster:集群
- Instance:實(shí)例
代碼注釋:We introduce a 'service --> cluster --> instance' model, in which service stores a list of clusters, which contains a list of instances
他們的關(guān)系如下
Service
- name:服務(wù)名
- protectThreshold:保護(hù)閾值题山,限制了實(shí)例被探活摘除的最大比例
- appName:服務(wù)的應(yīng)用名,暫無實(shí)際用處
- groupName:分組名
- metadata:元數(shù)據(jù)
Cluster
- serviceName:所屬服務(wù)名
- name:集群名
- healthChecker:服務(wù)探活配置故痊,此處僅對服務(wù)端主動探活生效顶瞳,有TCP、HTTP崖蜜、MySQL浊仆、None幾種方式,默認(rèn)TCP
- defaultPort:默認(rèn)端口
- defaultCheckPort:默認(rèn)探活端口
- useIPPort4Check:是否使用port進(jìn)行探活
- metadata:元數(shù)據(jù)
Instance
- instanceId:實(shí)例id豫领,唯一標(biāo)志,Nacos提供了
simple
和snowflake
兩種算法來生成舔琅,默認(rèn)是simple
等恐,其生成方式為ip#port#clusterName#serviceName
- ip:實(shí)例ip
- port:實(shí)例port
- weight:實(shí)例權(quán)重
- healthy:實(shí)例健康狀態(tài)
- clusterName:所屬集群名
- serviceName:所屬服務(wù)名
- metadata:元數(shù)據(jù)
- enabled:是否接收請求,可用于臨時禁用或摘流等場景
- ephemeral:是否為臨時實(shí)例备蚓,后文會介紹該參數(shù)
- getInstanceHeartBeatInterval:獲取實(shí)例心跳上報(bào)間隔時間课蔬,默認(rèn)5秒,可配置
- getInstanceHeartBeatTimeOut:獲取心跳超時時間郊尝,15秒二跋,配置
- getIpDeleteTimeout:獲取ip被刪除的超時時間,默認(rèn)30秒流昏,可配置
- getInstanceIdGenerator:獲取id生成器
除了上述的三層模型外扎即,Nacos注冊中心和配置中心有著一樣的namespace設(shè)計(jì)吞获,與client綁定,可隔離環(huán)境谚鄙,租戶各拷。
接口設(shè)計(jì)
- registerInstance:注冊實(shí)例
- deregisterInstance:注銷實(shí)例
- getAllInstances:獲取一個服務(wù)的所有實(shí)例(包括不健康)
- selectInstances:根據(jù)條件獲取一個服務(wù)的實(shí)例
- selectOneHealthyInstance:根據(jù)負(fù)載均衡策略獲取服務(wù)的一個健康的實(shí)例
- subscribe:訂閱服務(wù)
- unsubscribe:取消訂閱服務(wù)
- getServicesOfServer:根據(jù)條件分頁獲取所有服務(wù)
交互流程
Nacos 2.0 為ephemeral不同的實(shí)例提供了兩套流程:
- ephemeral=false,永久實(shí)例闷营,與server端的交互采用http請求烤黍,server節(jié)點(diǎn)間數(shù)據(jù)同步采用了raft協(xié)議,健康檢查采用了server端主動探活的機(jī)制
- ephemeral=true傻盟,臨時實(shí)例速蕊,與server端的交互采用grpc請求,server節(jié)點(diǎn)間數(shù)據(jù)同步采用了distro協(xié)議娘赴,健康檢查采用了TCP連接的KeepAlive模式
臨時實(shí)例的交互流程
-
client初始化互例,與server建立連接
- 只與其中一臺server節(jié)點(diǎn)建立長連接
-
client 注冊服務(wù),將serviceName+ip+port+clusterName等數(shù)據(jù)打包發(fā)送grpc請求
- 同時客戶端緩存已注冊過的服務(wù)筝闹,當(dāng)client與server連接斷開重連時媳叨,client重新將這些數(shù)據(jù)注冊到server端
-
server端接收到client的注冊請求,將注冊信息存入client對象(用于保存client的所有數(shù)據(jù))中关顷,并觸發(fā)ClientChangedEvent糊秆、ClientRegisterServiceEvent、InstanceMetadataEvent
- ClientChangedEvent觸發(fā)server節(jié)點(diǎn)之間的數(shù)據(jù)同步(distro協(xié)議)
- ClientRegisterServiceEvent觸發(fā)更新publisherIndexes(保存service => clientId的Map<Service, Set<String>>议双,即哪些客戶端注冊了這個服務(wù)的索引)痘番,同時也觸發(fā)一個ServiceChangedEvent,該事件負(fù)責(zé)向監(jiān)聽該服務(wù)的客戶端進(jìn)行推送
- InstanceMetadataEvent平痰,處理元數(shù)據(jù)汞舱,Nacos在2.0中將元數(shù)據(jù)與基礎(chǔ)數(shù)據(jù)拆分開,分為不同的處理流程
-
client訂閱服務(wù)
- 根據(jù)serviceName宗雇、groupName昂芜、clusters信息生成key,創(chuàng)建eventListener赔蒲,同時向server端發(fā)送訂閱請求泌神,并緩存訂閱信息,用于連接斷開重連后再次向server端發(fā)送信息
-
server端接收到client的訂閱請求
- 將訂閱信息打包為subscribers舞虱,并存入client對象中欢际,觸發(fā)ClientSubscribeServiceEvent事件
- ClientSubscribeServiceEvent事件更新subscriberIndexes(保存service => clientId的Map<Service, Set<String>>,即哪些客戶端訂閱了這個服務(wù)的索引)矾兜,同時觸發(fā)ServiceSubscribedEvent事件
- ServiceSubscribedEvent事件會延時500ms向該client推送該服務(wù)的最新數(shù)據(jù)
反向的操作如注銷损趋、取消訂閱與正向操作類似,不再贅述
最后
本文從總體上分析了Nacos 2.0的模型設(shè)計(jì)椅寺、接口設(shè)計(jì)以及交互流程浑槽,讀完后對Nacos的服務(wù)發(fā)現(xiàn)有一個整體上的認(rèn)識蒋失。
后續(xù)篇幅會從細(xì)節(jié)入手,如dubbo Nacos擴(kuò)展括荡、一致性協(xié)議高镐、探活、CMDB擴(kuò)展等逐一進(jìn)行分析畸冲。