springcloud源码分析之Eureka注册逻辑(一)

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>

我们看下这个包结构
image_1d8683l831cbgen71agilit1vpdm.png-72.9kB
我们看下这个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服务注册和服务发现的入口配置类。由于篇幅有限所以我下面就不墨迹了自己看吧 估计会被打死 所以我截取以下关键信息作为服务注册发现流程分析,细节就自己看哈。

项目结构说明

image_1d869ildv1lnm1lgh8muc5nhq1g.png-103.6kB

EurekaClientAutoConfiguration执行流程和关键点分析(客户端注册配置入口)

image_1d869bcvb13dlolm16sub8c1jfn13.png-108.1kB
我们来看下这个类主要的信息逻辑大于具体细节。

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;
}

image_1d869s7okd1l1sahaso13dk9qm1t.png-15.8kB
这个类主要是客户端配置类包括defaultZone等于服务端交互的相关配置
image_1d86a0dtt3u0p8f12m79qf190v3n.png-57.3kB

2.配置说明之EurekaInstanceConfigBean

image_1d86a3akeh6v1e509th1ra6qbd44.png-65.4kB
这个类主要是客户端信息的记录。用于注册到服务端

3.初始化EurekaClient

image.png-10.7kB
服务发现设计如下通过DiscovertyClient在springcloud包中定义接口主要用于心跳检测和服务获取逻辑。然后在Eureka中通过EurekaDiscoryClinet实现D…cient,其中真正的服务交互在netflix 的DiscoveryClient具体关系类图如下。
image.png-25.2kB
该设计结构以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 去启用心跳检测和注册逻辑(两个一起)。

因个人能力有限,如有不对欢迎指正!只要不是杠精的心态都虚心接受

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值