源码解析-Eureka Client(二)

1、Eureka Sever解析入口分析

(1)关于Marker实例

通过Eureka Server的依赖我们从spring.factories中找到EurekaServer的自动配置类。

该配置类具有一个条件注解:要求必须要有一个EurekaServerMarkerConæ guration.Marker实例这个配置类才会起作用。那么这个实例是在哪里创建的呢? 

打开Eureka Server的启动类,其必须要添加@EnableEurekaServer注解,为什么呢?

打开这个注解,其是一个复合注解,该注解中导入了一个类EurekaServerMarkerConæ gration。打开这个类,可以看到该类是一个配置类,在其中创建了Marker实例。

这就是为什么在EurekaServer启动类上必须添加@EnableEurekaServer注解的原因

 

(2)重要实例的创建

 

在这个Eureka Server自动配置类启动后,其会创建一个很重要的实例,InstanceRegistry。该实例及其父类中的很多方法是我们后面要调用到的。 

 

2、处理Client状态修改请求

Server完成的任务:
  • 修改了注册表中该instanceInfo的status
  • 将新的状态记录到了overriddenInstanceStatusMap缓存中
  • 本次修改记录到了recentlyChangedQueue缓存

  

3、处理客户端删除overridden状态请求

Server完成的任务:
  • 将指定Client的overriddenStatus从overriddenInstanceStatusMap中删除
  • 修改注册表中该Client的status为UNKNOWN
  • 将本次修改写入到recentlyChangedQueue缓存
  • 注意,并没有将该Client从注册表中进行删除 

 

4、处理客户端续约请求

Server完成的任务:计算出当前Client新的status,并将其写入到注册表。

5、Server间的数据同步

注意:变更配置文件时,会提交注册请求。

 

6、处理客户端下架请求

对比处理删除overridden状态请求与下架请求

处理删除overridden状态请求完成的主要任务:

  • 从缓存map中删除指定client的overriddenStatus
  • 修改注册表中该client的overriddenStatus为UNKNOWN
  • 修改注册表中该client的status为UNKNOWN
  • 将本次操作记录到recentlyChangedQueue
  • 修改注册表中该client的lastUpdatedTimestamp

处理下架请求完成的主要任务:

  • 将该client从注册表中删除
  • 从缓存map中删除指定client的overriddenStatus
  • 将本次操作记录到recentlyChangedQueue
  • 修改注册表中该client的lastUpdatedTimestamp

(蓝色字体为区别)

 

7、处理客户端注册请求

Server完成的任务:计算出当前Client新的status,并将其写入到注册表。

问题:为什么处理注册请求,写操作加读锁。处理续约时,写操作不加读锁?

问题:如何保证AP?

        this.numberOfRenewsPerMinThreshold = (int)
                (expectedNumberOfClientsSendingRenews
                        * (60.0 / serverConfig.getExpectedClientRenewalIntervalSeconds())
                        * serverConfig.getRenewalPercentThreshold())
        = (客户端数量 * (60 / 心跳间隔)*自我保护开启的阈值因子) 
        = (客户端数量 * 每个客户端每分钟发送心跳的数量 * 阈值因子)
        = (所有客户端每分钟发送的心跳数量 * 阈值因子) =当前Server开启自我保护机制的每分钟最小心跳数量

 

一旦自我保护机制开启了,那么就将当前Server保护了起来,即当前server注册表中的所有client均不会过期,即当client没有指定时间内(默认90秒)发送续约,也不会将其从注册表中删除。为什么?就是为了保证server的可用性,即保证AP。

expectedNumberOfClientsSendingRenews设置的越大,当前Server开启自我保护机制的每分钟最小心跳数量就越大,就越容易发生自我保护。 

 

8、处理客户端全量下载请求

获取负载源码:

8.1 问题1

readWriteCacheMap中的数据从哪里来?

答:在ResponseCacheImpl构造器中创建并初始化了这个读写缓存map。

8.2 问题2

readOnlyCacheMap的数据来自于readWriteCacheMap,但readWriteCacheMap中的数据若发生了变更,那么readOnlyCacheMap中的数据一定也需要发生变化,那么readOnlyCacheMap中的数据在最里发生的变更?

答:在ResponseCacheImpl构造器中定义并开启了一个定时任务,用于定时从readWriteCacheMap中更新readOnlyCacheMap中的数据。

8.3 问题3

为什么不直接从readWriteCacheMap中获取数据,而是从readOnlyCacheMap获取?即这种方案的好处是什么?

答:为了保证对readWriteCacheMap的迭代稳定性。即将读写进行了分离,分离到了两个共享集合。但这种解决方案存在一个很严重的弊端:读、写两个集合的数据无法保证强一致性,即只能做到最终一致性。所以这种方案的应用场景是,对数据的实时性要求不是很高,对数据是否是最新数据要求不高。

 

9、处理客户端增量下载请求

整体流程同“全量下载”大致相同

posted @ 2022-08-17 16:34  幻月hah  阅读(59)  评论(0编辑  收藏  举报