springcloud源码分析之Eureka注册逻辑(一)
标签(空格分隔): springcloud
Eureka是啥
eureka是netflix 公司开发的服务治理机制。包括注册中心,服务注册,服务发现三个角色。其中微服务一般自身即是服务发现者又是服务注册者。
eureka的server和client应用demo
放在github上作为demo 下载后可在本地运行 前提是有maven和java环境
github地址
Eureka流程分析
依赖和入口分析(springcloud版本 Finchley.RELEASE)
在我们maven导入如下cloud的start包的时候即引入了eureka-client相关包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
我们看下这个包结构
我们看下这个springboot自动配置工厂的信息
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.eureka.config.EurekaClientConfigServerAutoConfiguration,\
org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceAutoConfiguration,\
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\
org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,\
org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceBootstrapConfiguration
我们重点来看 EurekaClientAutoConfiguration这个就是Eureka服务注册和服务发现的入口配置类。由于篇幅有限所以我下面就不墨迹了自己看吧 估计会被打死 所以我截取以下关键信息作为服务注册发现流程分析,细节就自己看哈。
项目结构说明
EurekaClientAutoConfiguration执行流程和关键点分析(客户端注册配置入口)
我们来看下这个类主要的信息逻辑大于具体细节。
1.配置说明之EurekaClientConfigBean
这个类主要是用于配置client段连接到server端的相关配置
@Bean
@ConditionalOnMissingBean(value = EurekaClientConfig.class, search = SearchStrategy.CURRENT)
public EurekaClientConfigBean eurekaClientConfigBean(ConfigurableEnvironment env) {
EurekaClientConfigBean client = new EurekaClientConfigBean();
if ("bootstrap".equals(this.env.getProperty("spring.config.name"))) {
// We don't register during bootstrap by default, but there will be another 如果有config另行处理暂时先不注册
// chance later.
client.setRegisterWithEureka(false);
}
return client;
}
这个类主要是客户端配置类包括defaultZone等于服务端交互的相关配置
2.配置说明之EurekaInstanceConfigBean
这个类主要是客户端信息的记录。用于注册到服务端
3.初始化EurekaClient
服务发现设计如下通过DiscovertyClient在springcloud包中定义接口主要用于心跳检测和服务获取逻辑。然后在Eureka中通过EurekaDiscoryClinet实现D…cient,其中真正的服务交互在netflix 的DiscoveryClient具体关系类图如下。
该设计结构以cloud定义spi,netflix做拓展,以组合的形式实现具体逻辑。
其中netflix的DiscovertyClient是实现服务注册和心跳检测的主要实现逻辑。
具体逻辑如下:
统一入口构造
@Inject
DiscoveryClient(ApplicationInfoManager applicationInfoManager, EurekaClientConfig config, AbstractDiscoveryClientOptionalArgs args,
Provider<BackupRegistry> backupRegistryProvider) {
//应用信息管理(可在EurekaClientAutoConfigration中查看),交互配置/信息 .......
// finally, init the schedule tasks (e.g. cluster resolvers, heartbeat, instanceInfo replicator, fetch
initScheduledTasks();//这个方法就是服务注册,续约,获取的相关任务的入口方法
我们来看下initScheduledTasks方法
/**
* Initializes all scheduled tasks.
*/
private void initScheduledTasks() {
if (clientConfig.shouldFetchRegistry()) {//根据配置是否获取注册
// registry cache refresh timer
int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();
int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();
scheduler.schedule(//这个定时任务就是定时获取服务列表的入口
new TimedSupervisorTask(//如果您有时间可以看下具体的run方法
"cacheRefresh",
scheduler,
cacheRefreshExecutor,
registryFetchIntervalSeconds,
TimeUnit.SECONDS,
expBackOffBound,
new CacheRefreshThread()
),
registryFetchIntervalSeconds, TimeUnit.SECONDS);
}
if (clientConfig.shouldRegisterWithEureka()) {
int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();
logger.info("Starting heartbeat executor: " + "renew interval is: {}", renewalIntervalInSecs);
// Heartbeat timer 心跳检测的定时任务,尅看HearbeatThread里面的renew的方法就是对应的续约逻辑
scheduler.schedule(
new TimedSupervisorTask(
"heartbeat",
scheduler,
heartbeatExecutor,
renewalIntervalInSecs,
TimeUnit.SECONDS,
expBackOffBound,
new HeartbeatThread()
),
renewalIntervalInSecs, TimeUnit.SECONDS);
// InstanceInfo replicator 这个是注册逻辑在下方的start有就是入口
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()) {
// log at warn level if DOWN was involved
logger.warn("Saw local status change event {}", statusChangeEvent);
} else {
logger.info("Saw local status change event {}", statusChangeEvent);
}
instanceInfoReplicator.onDemandUpdate();
}
};
if (clientConfig.shouldOnDemandUpdateStatusChange()) {
applicationInfoManager.registerStatusChangeListener(statusChangeListener);
}
//开启注册任务 直接启用之后可看run方法可以看到注册逻辑
instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());
} else {
logger.info("Not registering with Eureka server per configuration");
}
}
捋一捋 整个逻辑就是从DiscoveryClient初始化开始,初始化定时任务,根据我们之前配置的相关信息是否获取 启用获取定时任务, 根据应该注册到eureka 去启用心跳检测和注册逻辑(两个一起)。
因个人能力有限,如有不对欢迎指正!只要不是杠精的心态都虚心接受