服务注册、心跳链接、服务下架、集群同步、自我保护机制

Eureka服务注册实际是利用了Jersey框架核心过滤器,拦截服务注册请求实现的。

服务注册 ApplicationResource#addInstance

心跳续约 InstanceResource#renewLease

集群同步

集群同步操作在PeerAwareInstanceRegistryImpl这个类中完成:
服务注册,服务下架,心跳续约,状态修改等操作均需要进行集群同步

服务剔除、服务下架 PeerAwareInstanceRegistryImpl#openForTraffic

通过上文分析,我们知道EurekaServer在初始化过程中会,设置一个服务剔除的定时器

自我保护机制

会在服务初始化,服务注册,服务下架,15分钟定时器自动触发
阈值算法:所有注册的实例 60s / 心跳续约时间默认30s 自我保护机制触发百分比默认85%

服务发现 ApplicationsResource#getContainers

源码精髓:多级缓存设计思想

在拉取注册表的时候:

  1. 首先从ReadOnlyCacheMap里查缓存的注册表。第⼀层缓存:readOnlyCacheMap,本质上是ConcurrentHashMap:这是⼀个JVM的CurrentHashMap只读缓存,这个主要是为了供客户端获取注册信息时使⽤,其缓存更新,依赖于定时器的更新,通过和readWriteCacheMap 的值做对⽐,如果数据不⼀致,则以readWriteCacheMap 的数据为准。readOnlyCacheMap 缓存更新的定时器时间间隔,默认为30秒
  2. 若没有,就找ReadWriteCacheMap里缓存的注册表。第⼆层缓存:readWriteCacheMap,本质上是Guava缓存:此处存放的是最终的缓存, 当服务下线,过期,注册,状态变更,都会来清除这个缓存⾥⾯的数据。 然后通过CacheLoader进⾏缓存加载,在进⾏readWriteCacheMap.get(key)的时候,⾸先看这个缓存⾥⾯有没有该数据,如果没有则通过CacheLoader的load⽅法去加载,加载成功之后将数据放⼊缓存,同时返回数据。 readWriteCacheMap 缓存过期时间,默认为 180 秒 。
  3. 如果还没有,就从内存中获取实际的注册表数据。

缓存机制:设置了⼀个每30秒执⾏⼀次的定时任务,定时去服务端获取注册信息。获取之后,存⼊本地内存。

在注册表发生变更的时候:

  1. 会在内存中更新变更的注册表数据,同时过期掉ReadWriteCacheMap。
  2. 此过程不会影响ReadOnlyCacheMap提供人家查询注册表。
  3. 默认每30秒Eureka Server会将ReadWriteCacheMap更新到ReadOnlyCacheMap里
  4. 默认每180秒Eureka Server会将ReadWriteCacheMap里是数据失效
  5. 下次有服务拉取注册表,又会从内存中获取最新的数据了,同时填充 各级缓存。

    多级缓存机制的优点:

    尽可能保证了内存注册表数据不会出现频繁的读写冲突问题。
    并且进一步保证对Eureka Server的大量请求,都是快速从纯内存走,性能极高(可以稍微估计下对于一线互联网公司,内部上千个eureka client实例,每分钟对eureka上千次的访问,一天就是上千万次的访问)