肝了三个工作日晚上的源码,总结的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间信息同步

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