3.3 DiscoveryClient 构造函数
在 DiscoveryClient 的构造函数中,会有如下操作,如:服注册表信息、服务注册、初始化发送心跳、缓存刷新、注册定时任务等。因此 DiscoveryClient 的构造函数贯穿了 Eureka Client 启动阶段的各项任务。
DiscoveryClient(ApplicationInfoManager applicationInfoManager, EurekaClientConfig config, AbstractDiscoveryClientOptionalArgs args,
Provider backupRegistryProvider, EndpointRandomizer endpointRandomizer) {
// 省略相关信息
}
在DiscoveryClient 的构造函数中有如下几个参数:ApplicationInfoManager、EurekaClientConfig、AbstractDiscoveryClientOptionalArgs、Provider
- 相关配置赋值,如ApplicationInfoManager、EurekaClientConfig等
- 备份注册中心初始化,默认没有实现
- 拉去 Eureka Server 注册表信息
- 注册前预处理
- 向 Eureka Server 注册自身
- 初始化定时任务、缓存刷新、按需注册定时任务
后面将会对这些步骤中对重要点进行相关分析。
4. Eureka Client 初始化
接下来我们看下DiscoveryClient 是怎样初始化的(构造方法中)。代码如下:
@Inject
DiscoveryClient(ApplicationInfoManager applicationInfoManager, EurekaClientConfig config, AbstractDiscoveryClientOptionalArgs args,
Provider backupRegistryProvider, EndpointRandomizer endpointRandomizer) {
...
// 如果开启拉取注册表的话
if (clientConfig.shouldFetchRegistry()) {
try {
// todo 拉取注册表信息
boolean primaryFetchRegistryResult = fetchRegistry(false);
if (!primaryFetchRegistryResult) {
logger.info("Initial registry fetch from primary servers failed");
}
...
}
}
...
// 如果进行服务注册的话 clientConfig.shouldEnforceRegistrationAtInit() 默认false
if (clientConfig.shouldRegisterWithEureka() && clientConfig.shouldEnforceRegistrationAtInit()) {
try {
// todo 进行服务注册
if (!register()) {
throw new IllegalStateException("Registration error at startup. Invalid server response.");
}
}
...
}
// finally, init the schedule tasks (e.g. cluster resolvers, heartbeat, instanceInfo replicator, fetch
// todo 定时任务
initScheduledTasks();
...
}
4.1 拉取注册表信息
// 如果开启拉取注册表的话
if (clientConfig.shouldFetchRegistry()) {
// 拉取注册表信息
boolean primaryFetchRegistryResult = fetchRegistry(false);
}
如果开启拉取注册信息,就会调用fetchRegistry 方法去Eureka Server上面拉取注册表信息。
private boolean fetchRegistry(boolean forceFullRegistryFetch) {
// If the delta is disabled or if it is the first time, get all
// applications
Applications applications = getApplications();
if (clientConfig.shouldDisableDelta() // 关闭增量,默认false
|| (!Strings.isNullOrEmpty(clientConfig.getRegistryRefreshSingleVipAddress()))
|| forceFullRegistryFetch
|| (applications == null)
|| (applications.getRegisteredApplications().size() == 0)
|| (applications.getVersion() == -1)) //Client application does not have latest library supporting delta
{
// todo 全量拉取注册表信息
getAndStoreFullRegistry();
} else {
// todo 增量更新
getAndUpdateDelta(applications);
}
// 设置hashCode
applications.setAppsHashCode(applications.getReconcileHashCode());
logTotalInstances();
}
可以看下最上面的注释,不启用增量 或者是第一次,就拉取全量注册表信息。
不启用增量|| 强制全量|| 本地注册表是空的, 这个时候就会调用getAndStoreFullRegistry 方法去Eureka Server 拉取全量注册表。 否则的话调用 getAndUpdateDelta 方法获取增量注册表信息。
4.1.1 全量拉取注册表信息
接下来我们看下getAndStoreFullRegistry 方法,看看是怎样拉取全量注册表的。