spring cloud学习--eureka 02
开启eureka client的注解@EnableDiscoveryClient的功能类DiscoveryClient梳理图

获取server url位于类EndpointUtils的getServiceUrlsMapFromConfig方法上
public static Map<String, List<String>> getServiceUrlsMapFromConfig(EurekaClientConfig clientConfig, String instanceZone, boolean preferSameZone) {
        Map<String, List<String>> orderedUrls = new LinkedHashMap();
        //获取regin,一个微服务应用只有一个region
        String region = getRegion(clientConfig);
        //获取zone,一个微服务可以有多个zone
        String[] availZones = clientConfig.getAvailabilityZones(clientConfig.getRegion());
        if (availZones == null || availZones.length == 0) {
            //如果zone为null,就设置为default
            availZones = new String[]{"default"};
        }
        logger.debug("The availability zone for the given region {} are {}", region, Arrays.toString(availZones));
        int myZoneOffset = getZoneOffset(instanceZone, preferSameZone, availZones);
        String zone = availZones[myZoneOffset];
        //根据region和zone得出server url, 并且可以配置多个server url
        List<String> serviceUrls = clientConfig.getEurekaServerServiceUrls(zone);
        if (serviceUrls != null) {
            orderedUrls.put(zone, serviceUrls);
        }
        int currentOffset = myZoneOffset == availZones.length - 1 ? 0 : myZoneOffset + 1;
        while(currentOffset != myZoneOffset) {
            zone = availZones[currentOffset];
            serviceUrls = clientConfig.getEurekaServerServiceUrls(zone);
            if (serviceUrls != null) {
                orderedUrls.put(zone, serviceUrls);
            }
            if (currentOffset == availZones.length - 1) {
                currentOffset = 0;
            } else {
                ++currentOffset;
            }
        }
        if (orderedUrls.size() < 1) {
            throw new IllegalArgumentException("DiscoveryClient: invalid serviceUrl specified!");
        } else {
            return orderedUrls;
        }
    }
服务注册DiscoveryClient initScheduledTasks方法
 private void initScheduledTasks() {
        int renewalIntervalInSecs;
        int expBackOffBound;
        if (this.clientConfig.shouldFetchRegistry()) {
            renewalIntervalInSecs = this.clientConfig.getRegistryFetchIntervalSeconds();
            expBackOffBound = this.clientConfig.getCacheRefreshExecutorExponentialBackOffBound();
            this.scheduler.schedule(new TimedSupervisorTask("cacheRefresh", this.scheduler, this.cacheRefreshExecutor, renewalIntervalInSecs, TimeUnit.SECONDS, expBackOffBound, new DiscoveryClient.CacheRefreshThread()), (long)renewalIntervalInSecs, TimeUnit.SECONDS);
        }
        //配置文件注册服务
        if (this.clientConfig.shouldRegisterWithEureka()) {
            renewalIntervalInSecs = this.instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
            expBackOffBound = this.clientConfig.getHeartbeatExecutorExponentialBackOffBound();
            logger.info("Starting heartbeat executor: renew interval is: " + renewalIntervalInSecs);
            this.scheduler.schedule(new TimedSupervisorTask("heartbeat", this.scheduler, this.heartbeatExecutor, renewalIntervalInSecs, TimeUnit.SECONDS, expBackOffBound, new DiscoveryClient.HeartbeatThread()), (long)renewalIntervalInSecs, TimeUnit.SECONDS);
            this.instanceInfoReplicator = new InstanceInfoReplicator(this, this.instanceInfo, this.clientConfig.getInstanceInfoReplicationIntervalSeconds(), 2);
            this.statusChangeListener = new StatusChangeListener() {
                public String getId() {
                    return "statusChangeListener";
                }
                public void notify(StatusChangeEvent statusChangeEvent) {
                    if (InstanceStatus.DOWN != statusChangeEvent.getStatus() && InstanceStatus.DOWN != statusChangeEvent.getPreviousStatus()) {
                        DiscoveryClient.logger.info("Saw local status change event {}", statusChangeEvent);
                    } else {
                        DiscoveryClient.logger.warn("Saw local status change event {}", statusChangeEvent);
                    }
                    DiscoveryClient.this.instanceInfoReplicator.onDemandUpdate();
                }
            };
            if (this.clientConfig.shouldOnDemandUpdateStatusChange()) {
                this.applicationInfoManager.registerStatusChangeListener(this.statusChangeListener);
            }
            //开启一个任务
            this.instanceInfoReplicator.start(this.clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());
        } else {
            logger.info("Not registering with Eureka server per configuration");
        }
    }
上面代码中 this.instanceInfoReplicator.start(this.clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());开启了一个任务,该任务的代码如下
public void run() {
        boolean var6 = false;
        ScheduledFuture next;
        label53: {
            try {
                var6 = true;
                this.discoveryClient.refreshInstanceInfo();
                Long dirtyTimestamp = this.instanceInfo.isDirtyWithTime();
                if (dirtyTimestamp != null) {
                    //真正触发了注册
                    this.discoveryClient.register();
                    this.instanceInfo.unsetIsDirty(dirtyTimestamp);
                    var6 = false;
                } else {
                    var6 = false;
                }
                break label53;
            } catch (Throwable var7) {
                logger.warn("There was a problem with the instance info replicator", var7);
                var6 = false;
            } finally {
                if (var6) {
                    ScheduledFuture next = this.scheduler.schedule(this, (long)this.replicationIntervalSeconds, TimeUnit.SECONDS);
                    this.scheduledPeriodicRef.set(next);
                }
            }
            next = this.scheduler.schedule(this, (long)this.replicationIntervalSeconds, TimeUnit.SECONDS);
            this.scheduledPeriodicRef.set(next);
            return;
        }
        next = this.scheduler.schedule(this, (long)this.replicationIntervalSeconds, TimeUnit.SECONDS);
        this.scheduledPeriodicRef.set(next);
    }
真正触发了注册的代码为this.discoveryClient.register();
注册的代码为:
boolean register() throws Throwable {
        logger.info("DiscoveryClient_" + this.appPathIdentifier + ": registering service...");
        EurekaHttpResponse httpResponse;
        try {
            //通过REST请求进行注册
            httpResponse = this.eurekaTransport.registrationClient.register(this.instanceInfo);
        } catch (Exception var3) {
            logger.warn("{} - registration failed {}", new Object[]{"DiscoveryClient_" + this.appPathIdentifier, var3.getMessage(), var3});
            throw var3;
        }
        if (logger.isInfoEnabled()) {
            logger.info("{} - registration status: {}", "DiscoveryClient_" + this.appPathIdentifier, httpResponse.getStatusCode());
        }
        return httpResponse.getStatusCode() == 204;
    }
spring cloud学习--eureka 02的更多相关文章
- spring cloud学习--eureka 01
		本博客为学习使用,学习教程翟永超 spring cloud 微服务实战 搭建eureka server注册中心 spring initialize构建spring boot项目 构建网址:https: ... 
- spring cloud 学习(9) - turbine stream无法在eureka注册的解决办法
		turbine是啥就不多解释了,初次接触的可以移步spring cloud 学习(4) - hystrix 服务熔断处理 拉到最后看一下,turbine stream默认情况下启动成功后,eureka ... 
- Spring Cloud学习(一):Eureka服务注册与发现
		1.Eureka是什么 Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的. Eureka ... 
- Spring Cloud 学习 之 Spring Cloud Eureka(源码分析)
		Spring Cloud 学习 之 Spring Cloud Eureka(源码分析) Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 ... 
- Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇
		Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇 本文主要内容: 1:spring cloud整合Eureka总结 本文是由凯哥(凯哥Java:kagejava ... 
- spring cloud之eureka简介
		最近线上的接口出了一些问题,有一些可能不是代码的问题,但是由于是测试和其他方面的同事爆出来的,所以感觉对接口的监控应该提上日程. 经过搜索发现,spring cloud的eureka就是专门做这方面工 ... 
- spring cloud 学习资料
		spring cloud 学习资料 网址 拜托!面试请不要再问我Spring Cloud底层原理 https://mp.weixin.qq.com/s/ZH-3JK90mhnJPfdsYH2yDA 
- Spring Boot和Spring Cloud学习资源推荐
		Spring Boot和Spring Cloud学习资源推荐 比较好的学习资源,分享一下. 1.Spring Boot官方文档:http://projects.spring.io/spring-b ... 
- Spring Cloud Security&Eureka安全认证(Greenwich版本)
		Spring Cloud Security&Eureka安全认证(Greenwich版本) 一·安全 Spring Cloud支持多种安全认证方式,比如OAuth等.而默认是可以直接添加spr ... 
随机推荐
- python模块 __name=='__main__' 用法
			python模块 __name=='__main__' 用法1.ceshi_mod1.pydef test1(): print('111111')def test2(): print('2222')i ... 
- PHP中的魔术方法总结:__construct,__destruct ,__call,__callStatic,__get,__set,__isset, __unset ,__sleep,__wakeup,__toString,__set_state,__clone,__autoload
			1.__get.__set这两个方法是为在类和他们的父类中没有声明的属性而设计的__get( $property ) 当调用一个未定义的属性时访问此方法__set( $property, $value ... 
- GeneXus笔记本—常用函数(上)
			国庆放假没事怎么办?写点笔记充会儿电! ≖‿≖✧ 哈哈哈 !!最近在参与公司的其中一个项目中,发现了一些函数自己没见过 也没使用过,但是这些函数都是GeneXus中自带的一些 这此记录的目的就是为 ... 
- 【Leetcode周赛】从contest-51开始。(一般是10个contest写一篇文章)
			Contest 51 (2018年11月22日,周四早上)(题号681-684) 链接:https://leetcode.com/contest/leetcode-weekly-contest-51 ... 
- Python 语音识别
			调用科大讯飞语音听写,使用Python实现语音识别,将实时语音转换为文字. 参考这篇博客实现的录音,首先在官网下载了关于语音听写的SDK,然后在文件夹内新建了两个.py文件,分别是get_audio. ... 
- C#高级编程笔记(22至25章节)文件\注册表\权限\事务
			22安全(using System.Security.Principal;) AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.Wi ... 
- logback为单独的包或者类配置输出文件
			最近接一个这样的需求,为某个类的日志输出到指定的文件.一般都是按日志级别输出到对应的文件中.查阅相关资料和logback教程,写出下面的demo供参考. 1.添加一个appender <!-- ... 
- dubbo-go 的开发、设计与功能介绍
			dubbo-go 的前世今生 dubbo-go 是目前 Dubbo 多语言生态最火热的项目.dubbo-go 最早的版本应该要追溯到 2016 年,由社区于雨同学编写 dubbo-go 的初版.当时很 ... 
- VMware vSphere(虚拟化平台)
			VMware vSphere 是业界领先且最可靠的虚拟化平台.vSphere将应用程序和操作系统从底层硬件分离出来,从而简化了 IT操作.您现有的应用程序可以看到专有资源,而您的服务器则可以作为资源池 ... 
- BZOJ 5137: [Usaco2017 Dec]Standing Out from the Herd(后缀自动机)
			传送门 解题思路 这个似乎和以前做过的一道题很像,只不过这个是求本质不同子串个数.肯定是先把广义\(SAM\)造出来,然后\(dfs\)时把子节点的信息合并到父节点上,看哪个只被一个串覆盖,\(ans ... 
