天天看點

Nacos源碼分析(四)Notifier異步處理Instance執行個體注冊流程

作者:愛好程式設計的程式員老徐

上文說到Notifier是一個線程類,其run方法的執行截圖如下:

Nacos源碼分析(四)Notifier異步處理Instance執行個體注冊流程

Notifier的run方法

可以看出run方法是一個死循環從阻塞隊列中取出一個Pair對象,上文說到調用了Notifier的addTask方法添加了一個Pair對象,接着調用handle方法,該方法截圖如下:

Nacos源碼分析(四)Notifier異步處理Instance執行個體注冊流程

Notifier的handle方法截圖

取出Pair對象中key和value,判斷DataOperation是否是CHANGE類型,注冊流程是CHANGE類型,是以調用了listener的onChange方法,而listener的實作類就是上文分析的Service對象,是以調用Service對象的onChange方法,該方法的截圖如下:

Nacos源碼分析(四)Notifier異步處理Instance執行個體注冊流程

Service的onChange方法

從方法截圖可以分析到周遊Instances對象的instanceList屬性,擷取其中執行個體,判斷執行個體的權重值,如果大于10000則設定為10000,如果小于0.01則設定為0.01的權重,接着調用updateIPs方法,根據Service對象的成員屬性clusterMap調用size方法重新建立了一個Map對象,其容量是clusterMap.size(),周遊clusterMap的key集合,key其實就是ClusterName的值,代表不同的叢集,往新Map中添加key,value的值是一個新建立的集合,然後周遊Instance集合,該集合代表不同的要注冊執行個體對象,擷取執行個體對象的ClusterName去新建立的Map中查找是Value值,由于Value是一個集合,把目前的Instance對象添加到集合中,此處源碼執行截圖如下:

Nacos源碼分析(四)Notifier異步處理Instance執行個體注冊流程

Service類的updateIPs方法截圖

Nacos源碼分析(四)Notifier異步處理Instance執行個體注冊流程

Service類的updateIps方法截圖

周遊新Map擷取Entry對象,擷取Entry對象的key值,取出原始Service對象成員屬性clusterMap根據key擷取 的value值,該value值是Cluster對象,調用該對象的updateIps方法,該方法的截圖如下:

Nacos源碼分析(四)Notifier異步處理Instance執行個體注冊流程

Cluster對象的updateIps方法截圖

該方法入參有兩個,一個是要注冊的對象集合,一個是是否臨時執行個體的标志,本例中是臨時執行個體,取出成員屬性ephemeralInstances集合的值,該值是一個臨時執行個體的Set集合,代表之前已經注冊過的執行個體集合,根據ephemeralInstances的集合元素個數建立一個Map集合,并命名為oldIpMap,把之前注冊的執行個體放到oldIpMap中,接着調用updatedIps方法,該方法截圖如下:

Nacos源碼分析(四)Notifier異步處理Instance執行個體注冊流程

Cluster對象的updatedIps方法截圖

求新舊執行個體交集,第一次沒有交接的執行個體,是以取完交集後為空,方法傳回到updateIps,接着調用subtract方法,該方法截圖如下:

Nacos源碼分析(四)Notifier異步處理Instance執行個體注冊流程

Cluster對象的subtract方法截圖

該方法的處理邏輯主要是從老的注冊執行個體往一個Map中放,key是ip和端口的組合,然後周遊新的注冊執行個體,判斷之前注冊的執行個體是否包含要注冊的執行個體,如果不包含添加到List<Instance>集中進行傳回,然後把要注冊的執行個體指派給Cluster成員屬性ephemeralInstances集合,此時新注冊執行個體完成注冊。

總結:

執行個體服務在伺服器端的注冊主要是異步進行注冊的,這樣做的好處是性能提升很大,因為注冊的服務不需要立馬被服務發現,背景一個個串行的執行可以提高伺服器端的并發注冊能力,下一節我将要分析服務發現的源碼,有興趣的同志歡迎在下方評論,如有不對的地方還請大家指教,謝謝大家。

繼續閱讀