Eureka Client状态更新同步

326 阅读3分钟

本文中源码,来自Eureka的v1.7.x版本。代码仓:github.com/Netflix/eur…

在上一篇文章《Eureka Client注册、续期和取消注册》中,我们了解了Eureka Client注册如何实现。 请考虑一个问题:

  • 当Eureka Client的状态发生变化时,比如从UP变为DOWN,如何及时同步给Eureka server?

默认续租周期是30秒,客户端在3个周期即90秒内没有续租,才会被Eureka server从注册表移除。总不能等这么久吧?

因此,需要一种更加及时的机制,让客户端将状态变化,及时同步给Eureka。这就是Eureka Client状态更新同步。

一 节点状态同步

InstanceInfoReplicator类,实现周期性刷新节点信息,有变动时向Eureka发起注册,将最新节点信息同步。

1.1 InstanceInfoReplicator类

该类的部分属性如下:

// 默认为30
private final int replicationIntervalSeconds;
// 调度线程池
private final ScheduledExecutorService scheduler;

// 限流器
private final RateLimiter rateLimiter;
// 缓冲量,默认为2
private final int burstSize;
// 每分钟执行次数,默认为4
private final int allowedRatePerMinute;

它实现了Runnable接口,run方法核心逻辑:

  1. 刷新节点信息(包括hostname、ip、心跳周期配置、续租过期配置、状态),有变化时设置isInstanceInfoDirty=true;
  2. 如果节点信息已变动,则向Eureka发起一次注册,并消除isInstanceInfoDirty标识;
  3. finally中提交下一次延迟任务 image.png image.png

1.2 创建并启动

在DiscoveryClient的构造器中,会调用initScheduledTasks(),有如下代码。 image.png 构造方法中:

  • 创建了仅有一个线程的调度线程池。
  • replicationIntervalSeconds默认为30秒,即每次执行的间隔时间。
  • 创建了限流器RateLimiter,allowedRatePerMinute默认为4。 image.png

然后调用start()方法,提交一个延迟任务。由于调用了setIsDirty(),将在run方法首次执行时,必然发起注册。 image.png image.png

二、StatusChangeListener接口

2.1 接口功能

StatusChangeListener是ApplicationInfoManager的嵌套类,声明了状态监听方法。 image.png

StatusChangeListener对象,需要添加到ApplicationInfoManager的listeners属性,调用registerStatusChangeListener方法即可。 image.png image.png

当调用ApplicationInfoManager.setInstanceStatus(),会触发已注册监听器的执行,同时设置InstanceInfo.isInstanceInfoDirty = trueimage.png

2.2 接口实现

在DiscoveryClient的构造方法中,对StatusChangeListener接口有一个实现:只在shouldOnDemandUpdateStatusChange为true时,才进行注册。 image.png 核心逻辑是:立即发起一次注册。 image.png

三 状态检查

onDemandUpdate方法有两处调用,其中一处是注册HealthCheckHandler时。 image.png image.png 将在springboot整合Eureka client时,看到对HealthCheckHandler的使用。

四 总结

源码中有4个场景,会引发Eureka客户端发起注册:

  • 在心跳任务启动后,将在一个心跳周期后(默认30秒)发起首次续租,eureka响应404,将引发一次注册;
  • 由InstanceInfoReplicator周期检查,在节点信息发生变化时,引发一次注册。
  • 调用ApplicationInfoManager#setInstanceStatus设置节点状态时,如果状态发生变化,将触发StatusChangeListener的执行,引起一次注册
  • 注册HealthCheckHandler时,引起一次注册

使用以上场景,可以在客户端状态变化时,立即同步给Eureka,而不用被动地等租期过期。