Eureka客户端源码-客户端初始化
Eureka源码阅读大概流程如下,先找到依赖jar文件,最终到DiscoveryClient 该类是客户端的核心类
初始化DiscoveryClient 这里把DiscoveryClient分4个部分进行描述
初始化执行器
private final ScheduledExecutorService scheduler;
private final ThreadPoolExecutor heartbeatExecutor;
private final ThreadPoolExecutor cacheRefreshExecutor;
//初始化调度器,2个核心线程
scheduler = Executors.newScheduledThreadPool(2,
new ThreadFactoryBuilder().
setNameFormat("DiscoveryClient-%d").
setDaemon(true).build());
//心跳执行器,核心线程1,最大线程可以配置,
heartbeatExecutor = new ThreadPoolExecutor(1,
clientConfig.getHeartbeatExecutorThreadPoolSize(),
0, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
new ThreadFactoryBuilder().
setNameFormat("DiscoveryClient-HeartbeatExecutor-%d").
setDaemon(true).build()
);
//本地注册表缓存刷新执行器
cacheRefreshExecutor = new ThreadPoolExecutor(1,
clientConfig.getCacheRefreshExecutorThreadPoolSize(),
0, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
new ThreadFactoryBuilder().
setNameFormat("DiscoveryClient-CacheRefreshExecutor-%d").
setDaemon(true).build()
);
- 获取注册信息前提配置允许从EurekaServer获取注册表,默认是true
//是否从EurekaServer获取注册信息
if (clientConfig.shouldFetchRegistry()) {
try {
//是否全量获取注册信息(传入的参数是false,表示不强制进行全量获取)
boolean primaryFetchRegistryResult = fetchRegistry(false);
boolean backupFetchRegistryResult = true;
//上面获取失败的时候才会执行fetchRegistryFromBackup()
//fetchRegistryFromBackup(从其他EuerkaServer或者本地进行获取注册表)
if (!primaryFetchRegistryResult && !fetchRegistryFromBackup()) {
backupFetchRegistryResult = false;
}
//上面两种方式都没有获取到,并且配置了 「强制在初始化时获取注册信息」为true,则抛出异常,默认是false
if (!primaryFetchRegistryResult && !backupFetchRegistryResult && clientConfig.shouldEnforceFetchRegistryAtInit()) {
throw new IllegalStateException("Fetch registry error at startup. Initial fetch failed.");
}
} catch (Throwable th) {
}
}
服务注册
//是否注册到Eureka 并且 在初始化的时候强制进行注册
if (clientConfig.shouldRegisterWithEureka() && clientConfig.shouldEnforceRegistrationAtInit()) {
//执行注册流程
if (!register() ) {
throw new IllegalStateException("Registration error at startup. Invalid server response.");
}
}
初始各种task
initScheduledTasks();
private void initScheduledTasks() {
//如果需要从EurekaServer获取注册信息
if (clientConfig.shouldFetchRegistry()) {
//配置注解参考上面的EurekaClientConfig配置注解
int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();
int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();
//本地缓存task
cacheRefreshTask = new TimedSupervisorTask("cacheRefresh",
scheduler, cacheRefreshExecutor,
registryFetchIntervalSeconds, TimeUnit.SECONDS,
expBackOffBound, new CacheRefreshThread());
//调度本地缓存task
scheduler.schedule(cacheRefreshTask, registryFetchIntervalSeconds, TimeUnit.SECONDS);
}
//如果需要注册到注册表
if (clientConfig.shouldRegisterWithEureka()) {
int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();
// 心跳Task
heartbeatTask = new TimedSupervisorTask("heartbeat",
scheduler, heartbeatExecutor,
renewalIntervalInSecs, TimeUnit.SECONDS,
expBackOffBound, new HeartbeatThread());
//开始调度心跳task
scheduler.schedule(heartbeatTask, renewalIntervalInSecs, TimeUnit.SECONDS);
// InstanceInfo复制器,实现Runnable接口,主要是更新本地的instanceInfo到EurekaServer上
instanceInfoReplicator = new InstanceInfoReplicator(this, instanceInfo,
clientConfig.getInstanceInfoReplicationIntervalSeconds(), 2); // burstSize
//状态变化监听器
statusChangeListener = new ApplicationInfoManager.StatusChangeListener() {
@Override
public String getId() {
return "statusChangeListener";
}
@Override
public void notify(StatusChangeEvent statusChangeEvent) {
if (InstanceStatus.DOWN == statusChangeEvent.getStatus() ||
InstanceStatus.DOWN == statusChangeEvent.getPreviousStatus()) {
}
//状态变化之后,进行instanceInfo更新
instanceInfoReplicator.onDemandUpdate();
}
};
//如果设置为true,本地InstanceInfo状态边个了,会注册或者更新到EurekaServer上
if (clientConfig.shouldOnDemandUpdateStatusChange()) {
applicationInfoManager.registerStatusChangeListener(statusChangeListener);
}
//启动,开始任务调度,调度的任务就是自身(instanceInfoReplicator) 主要是更新本地的InstanceInfo
instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());
}
}
总结
- 初始化EurekaClientConfig:主要是客户端的相关配置信息
- 初始化DiscoveryClient 核心类主要是用于获取注册信息、续约、更新、取消等操作
- 初始化并启动 本地注册表刷新定时任务、心跳定时任务、instance配置更新定时任务、
- 并根据配置是否发起注册流程