肝了三個工作日晚上的源碼,總結的Eureka客戶端與服務端的服務註冊

一、客戶端

代碼鏈路:
SpringBootApplication上使用註解@EnableDiscoveryClient --> @EnableDiscoveryClient 註解是用來啓用 DiscoveryClient(接口) 的實現(代碼類描述:Annotation to enable a DiscoveryClient implementation.)
--> EurekaDiscoveryClient中引用了 EurekaClient 類  --> EurekaClient的實現類 DiscoveryClient --> DiscoveryClient 的構造函數是服務註冊、服務續約、服務發現的入口

服務註冊整個過程總結:
S1:初始化操作 : 先調用了com.netflix.discovery.DiscoveryClient#getEurekaServiceUrlsFromConfig()方法,去獲取相關配置
S2:服務註冊 : com.netflix.discovery.DiscoveryClient 構造函數中調用了com.netflix.discovery.DiscoveryClient#initScheduledTasks方法
S3:initScheduledTasks方法中調用了異步註冊服務類InstanceInfoReplicator的start()方法,因爲InstanceInfoReplicator實現了Runnable接口,所以業務實現邏輯在run()方法中,在run()方法中調用了discoveryClient.register();
S4:服務註冊真正實現:httpResponse = eurekaTransport.registrationClient.register(instanceInfo);使用了http請求將元數據InstanceInfo請求到註冊中心。最後判斷httpResponse.getStatusCode() == 204返回布爾值

二、服務端

代碼鏈路:
SpringBootApplication上使用註解@EnableEurekaServer 
 --> EurekaServerAutoConfiguration 中通過@Bean註解初始化該對象PeerAwareInstanceRegistry(接口),真正邏輯在實現類中
 --> PeerAwareInstanceRegistryImpl#register()調用父類註冊方法super.register(info, leaseDuration, isReplication);
 --> AbstractInstanceRegistry#register(InstanceInfo registrant, int leaseDuration, boolean isReplication

只對服務註冊邏輯源碼閱讀總結:PeerAwareInstanceRegistryImpl#register(final InstanceInfo info, final boolean isReplication)
S1: 續約過期時間
    1.1先判斷租約信息對象是否爲空,並且持續時間是否大於0
    1.2如果上訴條件成立,取租約信息對象中的持續時間,否則取取租約信息對象中默認的持續時間,並且將持續時間傳遞到註冊方法中


S2:註冊應用實例信息
    2.1 調用父類AbstractInstanceRegistry的register(InstanceInfo registrant, int leaseDuration, boolean isReplication)
        註冊結構:private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry;第一層的key爲應用的AppName(InstanceInfo中這樣命名的,但含義就是服務的唯一id標識,所以這個服務名稱不能重複),第二層的key爲服務實例的InstanceId
                    com.netflix.appinfo.InstanceInfo:應用實例信息,LeaseInfo:應用實例信息的租約信息
    2.2 進來,使用讀寫鎖Lock read = readWriteLock.readLock();先加鎖 read.lock();
    2.3 根據AppName獲取到對應的Map<String, Lease<InstanceInfo>>多個應用實例信息爲gMap
    2.4 如果gMap爲空,則生成一個新的key爲AppName的ConcurrentHashMap<String, Lease<InstanceInfo>> gNewMap
    2.5 根據InstanceId獲取對應應用實例信息 existingLease
        2.5.1 如果InstanceId存在,直接返回
        2.5.2 如果InstanceId不存在,但DataCenterInfo中存在,則返回DataCenterInfo中的id
        2.5.3 如果上訴兩者都不滿足,則直接返回hostName
    2.6 註冊應用實例存在:如果existingLease不爲空,並且租約信息對應的持有者,即對應的應用實例也不爲空
    
    2.7 註冊應用實例不存在:如果existingLease爲空,或者租約信息對應的持有者爲空
    
    2.8 先構建Lease<InstanceInfo> lease租約信息對象,然後lease對象set值,最後把封裝好的lease對象put到gMap中

    
    2.9 根據InstanceStatus的狀態不是unknown,則封裝ConcurrentMap<String, InstanceStatus>以instanceId爲key,InstanceStatus爲value的overriddenInstanceStatusMap
    
    2.10 給InstanceInfo對象中set應用實例的狀態:
        2.10.1 如果InstanceStatus不是空,則給InstanceInfo對象中set應用實例的狀態setOverriddenStatus
        2.10.2 如果InstanceStatus是空,根據overridden status rules生成新的狀態並賦值給InstanceInfo對象的狀態字段setStatusWithoutDirty
    
    2.11 給InstanceInfo對象中set應用實例的上線的其他字段信息: registrant.setActionType,registrant.setLastUpdatedTimestamp
    2.12 釋放鎖 read.unlock();    
S3: Eureka-Server間信息同步

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章