Eureka Server啓動過程分析

1.首先,SpringCloud充分利用了SpringBoot的自動裝配特色
eureka-server的jar包,發如今META-INF下面的配置文件spring.factories,裏面記錄了Spring Boot啓動的時候會加載EurekaServerAutoConfiguration自動配置類
node

2.其次,分析EurekaServerAutoConfiguration類的源碼,咱們發現該類的類頭中存在@ConditionalOnBean的註解,如圖

他表明的意思是,若是想要裝配EurekaServerAutoConfigration,Spring容器中必需要有一個Marker的類的實例。
EurekaServerMarkerConfigration.Marker類:

咱們經過Find Usages功能查詢,在什麼樣的狀況下,咱們會向Spring容器中注入這個Marker對象

咱們發現,若是在Spring Cloud啓動過程當中添加@EnableEurekaServer註解,咱們就會向容器中添加這個Marker的實例對象。也就是說,@EnableEurekaServer註解是Spring Cloud自動加載EurekaServerAutoConfiguration的控制開關。web

3.再次,咱們須要研究加載EurekaServerAutoConfigration類後,會向容器中注入那些Bean,有那些操做

經過structure結構圖,咱們發現,EurekaServer類有一些自動逸的Codec實現,PeerEurekaNodes的回調接口。可是主要的,與EurekaServer啓動相關的Bean有6個:EurekaController、PeerAuareInstanceRegistry、PeerEurekaNodes、EurekaServerContext、EurekaServerBootstrap、FilterRegistationBean。
3.1 EurekaController

注入一個對外的接口——儀表盤/後臺界面,EurekaController。能夠在配置文件中關閉它,可是默認是開啓的狀態。eureka.dashboard.enabled=true算法

3.2 PeerAuareInstanceRegistry 和 PeerEurekaNodes

PeerAwareInstanceRegistry是一個對等節點感知實例註冊器(集羣模式下注冊服務使用到的註冊器)。而且值得注意的是,EurekaServer集羣模式中各個節點是對等的,沒有主從之分。(這一點和Zookeeper不同,zk經過ZAB協議實現了分佈式一致性,可是EurekaServer並無實現任何分佈式算法)
PeerEurekaNodes是用來輔助封裝對等節點相關的信息和操做,好比更新集羣中的對等節點。
這裏咱們稍微看下RefreshablePeerEurekaNodes的源碼,咱們發現它是在繼承PeerEurekaNodes的基礎上實現了ApplicationListener接口,該接口只定義了一個回調方法,處理事件的回調


實際上,實例化RefreshablePeerEurekaNodes對象仍是經過父類的構造方法完成的,這個在代碼的200行中有體現。spring

**3.3 **EurekaServerContext

向容器中注入了EurekaServerContext的對象,具體爲DefaultEurekaServerContext。翻閱DefaultEurekaServerContext源碼中,咱們發現它經過Spring的@PostConstruct註解調用了peerEurekaNodes對象的start()方法

具體在看一下64行調用的peerEurekaNodes.start()方法作了哪些操做

首先,定義了一個線程池Eureka-PeerNodesUpdater——Eureka的更新對等節點線程,最終start方法會開啓這個線程,不停調用93行所指向的updatePeerEurekaNodes()方法。
這個updatePeerEurekaNodes()方法會更新對等節點信息,由於EurekaServer節點可能會不斷的變化(好比,Eureka集羣中某個節點的上下線)
而updatePeerEurekaNodes()方法主要作了什麼呢?

其實就是Removing no longer available peer nodes和Adding new peer nodes。
至此,總結一下,EurekaServerContext的實例化過程,會啓動更新遠程對等節點的線程,不時的刷新遠程對等節點的信息。安全

3.4 EurekaServerBootstrap

注入EurekaServerBootstrap對象,後續的EurekaServer應用的啓動要依靠這個對象併發

3.5 FilterRegistrationBean

在Jersey框架下添加一個攔截器ServletContainer對象,攔截全部的/eureka/的請求,是的Jersey框架開始管理全部的/eureka/的請求框架

4.分析完EurekaServerAutoConfiguration具體注入哪些事情後,咱們在返回EurekaServerAutoConfiguration的類頭分析

它利用的Spring的@Import註解,在EurekaServerAutoConfigration注入完全部的Bean後,再次調用了EurekaServerInitializerConfigration對象,裝配了它。

因爲EurekaServerInitializerConfiguration實現了SmartLifecycle接口,全部Spring容器的Bean建立完成後會回調start()方法。(順便說一下,EurekaServerInitializerConfiguration類沒有顯式的無參方法,因此它的初始化會調用默認的無參構造方法,且幾乎不會作什麼操做)

而start()方法會開啓一個後臺線程去使用eurekaServerBootstrap對象初始化Context。分佈式

4.1 分析eurekaServerBootstrap對象的contextInitialized()方法(在3.4步驟時實例化的)

初始化上下文實際上就是初始化環境變量方法的調用和初始化EurekaServerContext()方法。其中initEurekaEnvironment()方法就是讀取配置,若是沒有配置則設置成默認配置

再看看initEurekaServerContext()方法

這個方法中大致分爲5步,1.註冊序列化的轉化器;2.對aws的狀況進行特殊處理;3.爲非IOC容器提供獲取serverContext對象接口;4.從其餘註冊中心複製註冊新信息;5.改變EurekaServer的狀態,EurekaServer啓動完成的標誌
這裏值得關注的是步驟4,如何複製其餘節點的註冊信息到本EurekaServer上。post

4.2 registry.syncUp()方法

這裏224行的register()方法是作把遠程得到過來的註冊信息註冊到本身的註冊表中(map中)

register()方法中具體就是在保證線程安全的狀況下對registry對象進行操做

綜上所述,registry.syncUp()方法就是拷貝其餘對等節點的註冊信息到本身的註冊表map中.net

4.3 registry.openForTraffic()方法

這裏,咱們確定選擇Peer的實現,由於Eureka Server的啓動通常都是集羣模式

openForTraffic()方法裏,具體就是設置實例狀態爲UP,並調用父類的postInit()方法

在com.netflix.eureka.registry.AbstractInstanceRegistry#postInit()方法中,主要是啓動失效剔除定時任務的,具體的任務邏輯在EvicationTask中定義。

這裏調用了 AbstractInstanceRegistry的evict()方法

這個方法就是根據失效時常剔除失效的服務
綜上所屬,registry.syncUp()就是開啓一個服務失效剔除線程

因此,
Eureka Server啓動過程就是在@EnableEurekaServer開關的基礎上,建立了一些後臺進程去同步註冊信息,併發佈一個Jersey的web服務。它充分利用了Spring Boot的自動裝配功能和spring的一些回調接口實現。

相關文章
相關標籤/搜索