07-Eureka服务发现核心源码解析
目录
3、Eureka服务发现核心源码解析
3.1、自动装载
3.2、服务注册
3.3、服务下架
3.4、心跳续约
3、Eureka服务发现核心源码解析
3.1、自动装载
在服务消费者导入的坐标中有 spring-cloud-netflix-eureka-client-2.1.0.RELEASE.jar 找到其中
的 spring.factories 可以看到所有自动装载的配置类
3.2、服务注册
boolean register() throws Throwable {
logger.info("DiscoveryClient_{}: registering service...",
this.appPathIdentifier);
EurekaHttpResponse httpResponse;
try {
httpResponse =
this.eurekaTransport.registrationClient.register(this.instanceInfo);
} catch (Exception var3) {
logger.warn("DiscoveryClient_{} - registration failed {}", new
Object[]{this.appPathIdentifier, var3.getMessage(), var3});
throw var3;
}
if (logger.isInfoEnabled()) {
logger.info("DiscoveryClient_{} - registration status: {}",
this.appPathIdentifier, httpResponse.getStatusCode());
}
return httpResponse.getStatusCode() ==
Status.NO_CONTENT.getStatusCode();
}
3.3、服务下架
@PreDestroy
public synchronized void shutdown() {
if (this.isShutdown.compareAndSet(false, true)) {
logger.info("Shutting down DiscoveryClient ...");
if (this.statusChangeListener != null && this.applicationInfoManager
!= null) {
this.applicationInfoManager.unregisterStatusChangeListener(this.statusChangeLis
tener.getId());
}
this.cancelScheduledTasks();
if (this.applicationInfoManager != null &&
this.clientConfig.shouldRegisterWithEureka() &&
this.clientConfig.shouldUnregisterOnShutdown()) {
this.applicationInfoManager.setInstanceStatus(InstanceStatus.DOWN);
this.unregister();
}
if (this.eurekaTransport != null) {
this.eurekaTransport.shutdown();
}
this.heartbeatStalenessMonitor.shutdown();
this.registryStalenessMonitor.shutdown();
logger.info("Completed shut down of DiscoveryClient");
}
}
3.4、心跳续约
在com.netflix.discovery.DiscoveryClient.HeartbeatThread中定义了续约的操作,我们查看renew()方法;
boolean renew() {
try {
EurekaHttpResponse<InstanceInfo> httpResponse =
this.eurekaTransport.registrationClient.sendHeartBeat(this.instanceInfo.getAppNa
me(), this.instanceInfo.getId(), this.instanceInfo, (InstanceStatus)null);
logger.debug("DiscoveryClient_{} - Heartbeat status: {}",
this.appPathIdentifier, httpResponse.getStatusCode());
if (httpResponse.getStatusCode() ==
Status.NOT_FOUND.getStatusCode()) {
this.REREGISTER_COUNTER.increment();
logger.info("DiscoveryClient_{} - Re-registering apps/{}",
this.appPathIdentifier, this.instanceInfo.getAppName());
long timestamp = this.instanceInfo.setIsDirtyWithTime();
boolean success = this.register();
if (success) {
this.instanceInfo.unsetIsDirty(timestamp);
}
return success;
} else {
return httpResponse.getStatusCode() ==
Status.OK.getStatusCode();
}
} catch (Throwable var5) {
logger.error("DiscoveryClient_{} - was unable to send heartbeat!",
this.appPathIdentifier, var5);
return false;
}
}
在renew()这个方法中,首先向注册中心执行了心跳续约的请求,StatusCode为200成功,若为404则执行register()重新注册操作;
最后总结一下eureka客户端做的事情;
1.根据配置文件初始化bean,创建客户端实例信息 InstanceInfo
2.第一次全量拉取注册中心服务列表(url=/apps),初始化周期任务:
2.1 CacheRefreshThread 定时刷新本地缓存服务列表,若是客户端第一次拉取,则会全量拉取,后面
则增量拉取.若增量拉取失败则全量拉取,配置属性为eureka.client.registryFetchIntervalSeconds=30默
认拉取一次;
2.2 HeartbeatThread 通过renew()续约任务,维持于注册中心的心跳(url=/apps/ {id}),若
返回状态码为404则说明该服务实例没有在注册中心注册,执行register()向注册中心注册实例信息;
2.3 ApplicationInfoManager.StatusChangeListener 注册实例状态监听类,监听服务实例状态变化,
向注册中心同步实例状态;
2.4 InstanceInfoReplicator 定时刷新实例状态,并向注册中心同步,默认
eureka.client.instanceInfoReplicationIntervalSeconds=30执行一次.若实例状态有变更,则重新执行注
册;

浙公网安备 33010602011771号