Eureka源码解析(1)

启动过程

众所周知,springboot应用启动的时候会加载classPath下jar包中spring.factories文件,而sringcloud正是充分利用了这一自动装配的特点,加载了eureka-server的EurekaServerAutoConfiguration配置类
在这里插入图片描述
直接进入配置类,首先看注解@ConditionalOnBean({Marker.class}),当Marker实例对象存在的时候该配置类才生效,也就是说需要有个maker bean才能装配到eureka-server,而这个marker由@EnableEurekaServer注解中组合注解决定,一个巧妙的开关注解就这样完成了。

再回到EurekaServerAutoConfiguration中,注入很多Bean,我们先看EurekaServerContext,注入了一个DefaultEurekaServerContext上下文,进入后会看到一个initialize()初始化方法被@PostConstruct所注解,也就是说在DefaultEurekaServerContext构建完后会执行这个方法。该方法中可以看到PeerAwareInstanceRegistry,PeerEurekaNodes的启动项。这两个Bean在主配置类中已经注入,进入this.peerEurekaNodes.start()。
在这里插入图片描述
可见该方法开启了线程池去更新什么东西,PeerEurekaNodes.this.resolvePeerUrls()该方法返回的是一个list集合,可以发现通过EurekaClient(用来给eureka-server注册实例的接口)获取可用的server-url,并且通过isThisMyUrl过滤了自身的url,然后进入updatePeerEurekaNodes。

protected void updatePeerEurekaNodes(List<String> newPeerUrls) {
        if (newPeerUrls.isEmpty()) {
        	//如果url为空就不更新
            logger.warn("The replica size seems to be empty. Check the route 53 DNS Registry");
        } else {
            Set<String> toShutdown = new HashSet(this.peerEurekaNodeUrls);
            toShutdown.removeAll(newPeerUrls);
            Set<String> toAdd = new HashSet(newPeerUrls);
            toAdd.removeAll(this.peerEurekaNodeUrls);
            if (!toShutdown.isEmpty() || !toAdd.isEmpty()) {
                List<PeerEurekaNode> newNodeList = new ArrayList(this.peerEurekaNodes);
                //移除不可用的节点
                if (!toShutdown.isEmpty()) {
                    logger.info("Removing no longer available peer nodes {}", toShutdown);
                    int i = 0;
					
                    while(i < newNodeList.size()) {
                        PeerEurekaNode eurekaNode = (PeerEurekaNode)newNodeList.get(i);
                        if (toShutdown.contains(eurekaNode.getServiceUrl())) {
                            newNodeList.remove(i);
                            eurekaNode.shutDown();
                        } else {
                            ++i;
                        }
                    }
                }
				//通过http添加新的节点信息
                if (!toAdd.isEmpty()) {
                    logger.info("Adding new peer nodes {}", toAdd);
                    Iterator var7 = toAdd.iterator();

                    while(var7.hasNext()) {
                        String peerUrl = (String)var7.next();
                        newNodeList.add(this.createPeerEurekaNode(peerUrl));
                    }
                }
				//节点与URL集合更新
                this.peerEurekaNodes = newNodeList;
                this.peerEurekaNodeUrls = new HashSet(newPeerUrls);
            }
        }
    }

由此可知updatePeerEurekaNodes是用来更新集群节点信息的,主配置类所注入的PeerEurekaNode等同于对等节点信息封装操作的Bean,PeerEurekaNode的子类RefreshablePeerEurekaNodes监听了环境变化动态更新节点信息同样注入主配置类中。
在这里插入图片描述
回到context中,往下this.registry.init(this.peerEurekaNodes),关于server端的一些初始化操作,比如ResponseCacheImpl的缓存初始化,这边先跳过。
回到主配置类中,再看注解@Import({EurekaServerInitializerConfiguration.class}),EurekaServerInitializerConfiguration中实现了SmartLifecycle,SmartLifecycle是spring容器的bean创建完成后执行start方法做一些事情,重点关注start中的this.eurekaServerBootstrap.contextInitialized(this.servletContext),初始化了EurekaServerContext的细节,跟进initEurekaServerContext这个方法:

protected void initEurekaServerContext() throws Exception {
        JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), 10000);
        XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), 10000);
        if (this.isAws(this.applicationInfoManager.getInfo())) {
            this.awsBinder = new AwsBinderDelegate(this.eurekaServerConfig, this.eurekaClientConfig, this.registry, this.applicationInfoManager);
            this.awsBinder.start();
        }

        EurekaServerContextHolder.initialize(this.serverContext);
        log.info("Initialized server context");
        **//
        	从集群中的server同步注册信息
        **
        int registryCount = this.registry.syncUp();
        this.registry.openForTraffic(this.applicationInfoManager, registryCount);
        EurekaMonitors.registerAllStats();
    }
public int syncUp() {
        int count = 0;
		//重试
        for(int i = 0; i < this.serverConfig.getRegistrySyncRetries() && count == 0; ++i) {
            if (i > 0) {
                try {
                    Thread.sleep(this.serverConfig.getRegistrySyncRetryWaitMs());
                } catch (InterruptedException var10) {
                    logger.warn("Interrupted during registry transfer..");
                    break;
                }
            }
			//远程注册表信息
            Applications apps = this.eurekaClient.getApplications();
            Iterator var4 = apps.getRegisteredApplications().iterator();

            while(var4.hasNext()) {
                Application app = (Application)var4.next();
                Iterator var6 = app.getInstances().iterator();

                while(var6.hasNext()) {
                    InstanceInfo instance = (InstanceInfo)var6.next();

                    try {
                        if (this.isRegisterable(instance)) {
                        	***//
                        	同步到自己的内存中
                        	//***
                            this.register(instance, instance.getLeaseInfo().getDurationInSecs(), true);
                            ++count;
                        }
                    } catch (Throwable var9) {
                        logger.error("During DS init copy", var9);
                    }
                }
            }
        }

        return count;
    }

由此得知PeerAwareInstanceRegistry,是一个感知对等节点的注册器,对于新server加入集群,服务注册,服务心跳以及剔除自我保护时候的影响的感知。

总结:
1)通过marker控制配置类加载
2)context去启动更新eureka对等节点信息
3)初始化了EurekaServerContext的细节去感知新server加入集群,服务注册,服务心跳以及剔除自我保护时候的影响的感知

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值