二、Eureka源码解析:服务注册以及注册信息的更改(包含客户端和服务的源码详解)

1、 spring-cloud-netflix-eureka-client-1.4.0.RELEASE.jar是个重要的jar包,很多配置都在此jar内部的spring.factories文件中,首先要确定这个jar包是否会出现在应用的classpath中(如果不在classpath中,这些配置就不会生效),在pom.xml所在目录下执行命令mvn dependency:tree,打印依赖树,如下图,可确认spring-cloud-netflix-eureka-client被启动器spring-cloud-starter-netflix-eureka-client间接依赖,因此会出现在classpath中。

2.通过 spring-cloud-netflix-eureka-client-1.4.0.RELEASE.jar中的spring.factories文件

springboot启用了自动配置,那么EurekaClientConfigServerAutoConfiguration、……、EurekaDiscoveryClientConfiguration等五个配置类都会生效;

3. 按照spring.factories中的配置,EurekaClientAutoConfiguration中的配置都会生效,包括下面这段代码返回的bean:

@Bean

public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) {

    return new EurekaDiscoveryClient(config, client);

}

4. spring容器初始化时会实例化所有单例bean,就会执行EurekaClientAutoConfiguration的discoveryClient方法获取这个bean实例,于是就构造了一个EurekaDiscoveryClient对象;

5. 注意EurekaDiscoveryClient的构造方法,第二个入参是com.netflix.discovery.EurekaClient类型,此对象同样来自EurekaClientAutoConfiguration类,如下方法:

 

@Bean(destroyMethod = "shutdown")

@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)

@org.springframework.cloud.context.config.annotation.RefreshScope

@Lazy

public EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config, EurekaInstanceConfig instance) {

    manager.getInfo(); // force initialization

    return new CloudEurekaClient(manager, config, this.optionalArgs,this.context);

}

CloudEurekaClient的父类com.netflix.discovery.DiscoveryClient来自netflix发布的eureka-client包中,所以可以这么理解:EurekaDiscoveryClient类是个代理身份,真正的服务注册发现是委托给netflix的开源包来完成的,我们可以专心的使用SpringCloud提供的服务注册发现功能,只需要知道EurekaDiscoveryClient即可,真正的服务是eureka-client来完成的;

 

6. 接下来需要关注com.netflix.discovery.DiscoveryClient的构造方法,因为这里面有服务注册的逻辑,整个构造方法内容太多,无需都细看,只看关键代码即可;

 

7. DiscoveryClient的构造方法中,最熟悉的应该是下图红框中这段日志输出的了:

9. initScheduledTasks方法的内容如下,请注意中文注释:

private void initScheduledTasks() {

    //获取服务注册列表信息

        if (clientConfig.shouldFetchRegistry()) {

            //服务注册列表更新的周期时间

            int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();

            int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();

            //定时更新服务注册列表

            scheduler.schedule(

                    new TimedSupervisorTask(

                            "cacheRefresh",

                            scheduler,

                            cacheRefreshExecutor,

                            registryFetchIntervalSeconds,

                            TimeUnit.SECONDS,

                            expBackOffBound,

                            new CacheRefreshThread() //该线程执行更新的具体逻辑

                    ),

                    registryFetchIntervalSeconds, TimeUnit.SECONDS);

        }

 

        if (clientConfig.shouldRegisterWithEureka()) {

            //服务续约的周期时间

            int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();

            int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();

            //应用启动可见此日志,内容是:Starting heartbeat executor: renew interval is: 30

            logger.info("Starting heartbeat executor: " + "renew interval is: " + renewalIntervalInSecs);

            // 定时续约

            scheduler.schedule(

                    new TimedSupervisorTask(

                            "heartbeat",

                            scheduler,

                            heartbeatExecutor,

                            renewalIntervalInSecs,

                            TimeUnit.SECONDS,

                            expBackOffBound,

                            new HeartbeatThread() //该线程执行续约的具体逻辑

                    ),

                    renewalIntervalInSecs, TimeUnit.SECONDS);

 

            //这个Runable中含有服务注册的逻辑

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

                    }

                    i

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值