版本 awsVersion = ‘1.11.277’
DiscoveryClient # cacheRefreshTask
// 配置shouldFetchRegistry
if (clientConfig.shouldFetchRegistry()) {// 配置client.refresh.intervalint registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();// 配置expBackOffBoundint expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();cacheRefreshTask = new TimedSupervisorTask("cacheRefresh",scheduler,cacheRefreshExecutor,registryFetchIntervalSeconds,TimeUnit.SECONDS,expBackOffBound,new CacheRefreshThread());scheduler.schedule(cacheRefreshTask,registryFetchIntervalSeconds, TimeUnit.SECONDS);
}
shouldFetchRegistry
指定是否从服务端拉取注册列表,默认 true
client.refresh.interval
指定从服务端拉取注册列表的时间间隔,默认 30s
client.cacheRefresh.exponentialBackOffBound
指定从服务端拉取注册列表的最大时间间隔,默认 10
注1:当从服务端拉取注册列表的请求超时(即 TimedSupervisorTask 捕获 TimeoutException 异常时),下一次拉取的时间间隔会成倍递增,递增后的时间间隔不能超过 client.cacheRefresh.exponentialBackOffBound
和 client.refresh.interval
的乘积(即拉取的时间间隔最大不能超过 10x30=300s)
注2:
supervisor
英
/ˈsuːpəvaɪzə®/
美
/ˈsuːpərvaɪzər/
n.
监督人;主管人;指导者
注3:
exponential
英
/ˌekspəˈnenʃl/
美
/ˌekspəˈnenʃl/
adj.
指数的;幂的;越来越快的;由指数表示的
n.
指数
DiscoveryClient # heartbeatTask
if (clientConfig.shouldRegisterWithEureka()) {int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();heartbeatTask = new TimedSupervisorTask("heartbeat",scheduler,heartbeatExecutor,renewalIntervalInSecs,TimeUnit.SECONDS,expBackOffBound,new HeartbeatThread());scheduler.schedule(heartbeatTask,renewalIntervalInSecs, TimeUnit.SECONDS);
}
registration.enabled
指定是否向服务端注册实例,默认 true
lease.renewalInterval
指定向服务端续约的时间间隔,默认 30s
lease.duration
指定向服务端续约的租期时间,默认 90s
client.heartbeat.exponentialBackOffBound
指定向服务端续约的最大时间间隔,默认 10
注1:当向服务端续约的请求超时(即 TimedSupervisorTask 捕获 TimeoutException 异常时),下一次进行续约的时间间隔会成倍递增,递增后的时间间隔不能超过 client.heartbeat.exponentialBackOffBound
和 lease.renewalInterval
的乘积(即进行续约的时间间隔最大不能超过 10x30=300s)
DiscoveryClient # instanceInfoReplicator
// 配置registration.enabled
if (clientConfig.shouldRegisterWithEureka()) {// ...instanceInfoReplicator = new InstanceInfoReplicator(this,instanceInfo,// 配置appinfo.replicate.intervalclientConfig.getInstanceInfoReplicationIntervalSeconds(),// burstSize2);statusChangeListener = new ApplicationInfoManager.StatusChangeListener(){@Overridepublic void notify(StatusChangeEvent statusChangeEvent) {instanceInfoReplicator.onDemandUpdate();}};// 配置shouldOnDemandUpdateStatusChangeif (clientConfig.shouldOnDemandUpdateStatusChange()) {applicationInfoManager.registerStatusChangeListener(statusChangeListener);}instanceInfoReplicator.start(// 配置appinfo.initial.replicate.timeclientConfig.getInitialInstanceInfoReplicationIntervalSeconds());
}
registration.enabled
指定是否向服务端注册实例,默认 true
appinfo.replicate.interval
指定向服务端注册实例的时间间隔,默认 30s
appinfo.initial.replicate.time
指定初次向服务端注册实例的延迟时间,默认 40s
shouldOnDemandUpdateStatusChange
指定是否启用 StatusChangeListener,在实例状态更新时向服务端注册实例,默认 true
客户端通过 InstanceInfoReplicator 向服务端注册实例,有以下两种方式:
- scheduler 周期地
异步执行
InstanceInfoReplicator 的 run 方法
public void run() {try {// 刷新实例信息discoveryClient.refreshInstanceInfo();Long dirtyTimestamp = instanceInfo.isDirtyWithTime();// 如果实例信息发生了更新if (dirtyTimestamp != null) {// 向服务端注册实例discoveryClient.register();// 重置实例的dirty状态instanceInfo.unsetIsDirty(dirtyTimestamp);}} catch (Throwable t) {} finally {// scheduler进行下一次延迟调度Future next = scheduler.schedule(this, replicationIntervalSeconds, TimeUnit.SECONDS);scheduledPeriodicRef.set(next);}
}
- 实例状态发生变化时,statusChangeListener
同步触发
InstanceInfoReplicator 的 onDemandUpdate 方法,scheduler异步执行
InstanceInfoReplicator 的 run 方法
public boolean onDemandUpdate() {// 令牌桶限流,如果rateLimiter成功获取令牌if (rateLimiter.acquire(burstSize, allowedRatePerMinute)) {// 如果scheduler没有关闭if (!scheduler.isShutdown()) {scheduler.submit(new Runnable() {@Overridepublic void run() {Future latestPeriodic = scheduledPeriodicRef.get();// 如果scheduler正在执行则取消if (latestPeriodic != null && !latestPeriodic.isDone()) {latestPeriodic.cancel(false);}InstanceInfoReplicator.this.run();}});return true;} // end if (!scheduler.isShutdown())} // end if (rateLimiter.acquire(burstSize, allowedRatePerMinute))
}