官方wiki:https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
使用@EnableEurekaClient注解后springboot会自动配置EurekaClientAutoConfiguration,初始化DiscoveryClient
@Bean
public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) {
return new EurekaDiscoveryClient(config, client);
}
DiscoveryClient依赖单例模式的EurekaClient,实例化EurekaClient实现类DiscoveryClient
@Singleton
public class DiscoveryClient implements EurekaClient {
DiscoveryClient初始化构造方法
任务调度器
private final ScheduledExecutorService scheduler;
心跳线程池(向eureka-server注册/续约的池子)
// additional executors for supervised subtasks
private final ThreadPoolExecutor heartbeatExecutor;
缓存刷新线程池(从eureka-server拉取和更新注册表信息的池子)
private final ThreadPoolExecutor cacheRefreshExecutor;
// default size of 2 - 1 each for heartbeat and cacheRefresh
scheduler = Executors.newScheduledThreadPool(2,
new ThreadFactoryBuilder()
.setNameFormat("DiscoveryClient-%d")
.setDaemon(true)
.build());
heartbeatExecutor = new ThreadPoolExecutor(
1, clientConfig.getHeartbeatExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
new SynchronousQueue(),
new ThreadFactoryBuilder()
.setNameFormat("DiscoveryClient-HeartbeatExecutor-%d")
.setDaemon(true)
.build()
); // use direct handoff
cacheRefreshExecutor = new ThreadPoolExecutor(
1, clientConfig.getCacheRefreshExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
new SynchronousQueue(),
new ThreadFactoryBuilder()
.setNameFormat("DiscoveryClient-CacheRefreshExecutor-%d")
.setDaemon(true)
.build()
); // use direct handoff
初始化任务调度initScheduledTasks()方法,调用refreshRegistry()方法,再调用fetchRegistry(remoteRegionsModified)
// if源码里面一大堆判断,判断是否初始化;初始化是获取和保存,已经初始化了则做更新
if (true) {
getAndStoreFullRegistry();
} else {
getAndUpdateDelta(applications);
}
通过http请求获取到信息然后保存或更新到本地
com.netflix.discovery.shared.Applications apps = httpResponse.getEntity();
localRegionApps.set(this.filterAndShuffle(apps));
// 初始化时,获取eureka-server所有注册表信息保存到本地
private Applications filterAndShuffle(Applications apps) {
if (apps != null) {
if (isFetchingRemoteRegionRegistries()) {
Map remoteRegionVsApps = new ConcurrentHashMap();
apps.shuffleAndIndexInstances(remoteRegionVsApps, clientConfig, instanceRegionChecker);
for (Applications applications : remoteRegionVsApps.values()) {
applications.shuffleInstances(clientConfig.shouldFilterOnlyUpInstances());
}
this.remoteRegionVsApps = remoteRegionVsApps;
} else {
apps.shuffleInstances(clientConfig.shouldFilterOnlyUpInstances());
}
}
return apps;
}
com.netflix.discovery.shared.Applications delta = httpResponse.getEntity();
updateDelta(delta);
// 更新时,获取仅有更新的注册表信息到本地进行更新
private void updateDelta(Applications delta) {
int deltaCount = 0;
for (Application app : delta.getRegisteredApplications()) {
for (InstanceInfo instance : app.getInstances()) {
Applications applications = getApplications();
String instanceRegion = instanceRegionChecker.getInstanceRegion(instance);
if (!instanceRegionChecker.isLocalRegion(instanceRegion)) {
Applications remoteApps = remoteRegionVsApps.get(instanceRegion);
if (null == remoteApps) {
remoteApps = new Applications();
remoteRegionVsApps.put(instanceRegion, remoteApps);
}
applications = remoteApps;
}
++deltaCount;
if (ActionType.ADDED.equals(instance.getActionType())) {
...新增实例
} else if (ActionType.MODIFIED.equals(instance.getActionType())) {
...修改实例
} else if (ActionType.DELETED.equals(instance.getActionType())) {
...删除实例
}
}
}
logger.debug("The total number of instances fetched by the delta processor : {}", deltaCount);
getApplications().setVersion(delta.getVersion());
getApplications().shuffleInstances(clientConfig.shouldFilterOnlyUpInstances());
for (Applications applications : remoteRegionVsApps.values()) {
applications.setVersion(delta.getVersion());
applications.shuffleInstances(clientConfig.shouldFilterOnlyUpInstances());
}
}