Eureka的注册表拉取及多级缓存机制简析

Eureka作为注册中心想必大家都不陌生了,注册中心简单来说,其实就是各个服务将自己的IP和端口号这些信息存放到注册中心里,形成一个注册表,当服务间调用的时候,调用方就能从注册中心的注册表里面获取到要调用服务的具体IP和端口号,就可以请求那个服务了

Eureka的注册表拉取机制分为了两种,第一种是第一次拉取服务注册表的时候,此时需要全量拉取注册表,将所有服务的注册表信息全部存放起来,第二种是每隔30秒,增量拉取服务注册表

在eureka client拉取注册表的时候,就会用到所谓的多级缓存机制,多级缓存机制中有两个缓存,一个叫只读缓存ReadOnlyCacheMap,一个叫读写缓存ReadWriteCacheMap。eureka client拉取注册表的时候,会先从ReadOnlyCacheMap中去获取注册表数据,如果获取不到的话再去ReadWriteCacheMap中找,如果还是找不到的话,那就只能重新从注册表中拉取了

ReadOnlyCacheMap就是一个普通的ConcurrentHashMap,而ReadWriteCacheMap是guava cache,如果ReadWriteCacheMap读不到数据,就会通过ClassLoader的load方法直接从注册表获取数据再返回

多级缓存机制有多种过期策略

  • 主动过期:当服务实例发生注册、下线、故障的时候,ReadWriteCacheMap中所有的缓存过期掉
  • 定时过期:readWriteCacheMap在构建的时候,指定了一个自动过期的时间,默认值就是180秒,所以你往readWriteCacheMap中放入一个数据,180秒过后,就将这个数据给他过期了
  • 被动过期:默认是每隔30秒,执行一个定时调度的线程任务,对readOnlyCacheMap和readWriteCacheMap中的数据进行一个比对,如果两块数据是不一致的,那么就将readWriteCacheMap中的数据放到readOnlyCacheMap中来

通过过期的机制,可以发现一个问题,就是如果ReadWriteCacheMap发生了主动过期或定时过期,此时里面的缓存就被清空或部分被过期了,但是在此之前readOnlyCacheMap刚执行了被动过期,发现两个缓存是一致的,就会接着使用里面的缓存数据

所以可能会存在30秒的时间,readOnlyCacheMap和ReadWriteCacheMap的数据不一致

在这里插入图片描述
服务注册表的全量拉取很好理解,就是第一次的时候,从注册表全量拉取注册表到eureka client,后面的话就是增量拉取了

增量拉取注册表的实现借助了一个ConcurrentLinkedQueue类型的变量recentlyChangedQueue,通过名称我们就能知道这个变量的含义,最近改变的队列,默认情况下recentlyChangedQueue里面存放的是180秒内修改的服务实例信息,后台会有一个定时任务来维护recentlyChangedQueue,只有最近180秒内有变更的服务实例才会在里面

在增量拉取注册表时,会将本地的注册表和recentlyChangedQueue中的服务实例进行一个合并,将有变化的服务实例信息进行一个修改,保证本地的服务注册表信息和eureka server的服务注册表一致

在获取增量注册表信息的时候,同时获取了一个eureka server全量注册表的hash值,这个又是干什么用的呢?在eureka client增量同步注册表完成之后,也会计算一个hash值,然后将自己计算出来的这个hash值和eureka server全量注册表的hash值进行比对,如果是一致的,说明增量数据同步没问题,反之则说了增量数据同步出现了不一致,那么就会重新从eureka server全量拉取一份最新的服务注册表

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38420688/article/details/108684492