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执行一次.若实例状态有变更,则重新执行注
册;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!