SpringCloud注册中心Eureka源码分析(一)

SpringCloud注册中心Eureka源码分析

首先,对于服务注册中心、服务提供者、服务消费者这三个主要元素来说,后两者在整个运行机制中是大部分通信行为的主动发起者,而注册中心主要是处理请求的接收者。所以,我们可以从Eureka的客户端作为入口看看它们是如何完成这些主动通信行为的。

@我们将springboot应用注册到eureka注册中心或则从注册中心获取服务列表主要做了一下两件事情:

  1. 在应用主类中配置@EnableDiscoveryClient注解。
  2. 在application.properties中用eureka.client.serviceUrl.defaultZone参数指定了服务注册中心的位置。
    顺着上面的线索我们来看看@EnableDiscoveryClient的源码,具体如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({EnableDiscoveryClientImportSelector.class})
public @interface EnableDiscoveryClient {
    boolean autoRegister() default true;
}

从该注解的注释中我们可以知道,它主要用来开启DiscoveryClient的实例。通过搜索DiscoveryClient,我们可以发现有一个类和一个接口。通过梳理可以得到如下关系:
在这里插入图片描述
解读DiscoveryClient类:

  • 向eureka server注册服务实例
  • 向eureka server服务租约
  • 当服务关闭期间,向eureka server取消租约
  • 查询eureka server 中的服务实例列表
    eureka client 还需要配置一个eureka server 的URL列表
    在具体研究eureka client负责完成的任务之前,我们先看看在哪里对eureka server的URL列表进行配置。根据我们配置的属性名eureka.client.serviceUrl.defaultZone,通过serviceUrl可以找到该属性相关的加载属性,但是在SR5版本之后他们都被@Deprecated标注为不再建议使用,并@link到了替代类com.netflix.discovery.endpoint.EndpointUtils,所以我们可以在该类中找到下面这个函数
public static List<String> getServiceUrlsFromConfig(EurekaClientConfig clientConfig, String instanceZone, boolean preferSameZone) {
        List<String> orderedUrls = new ArrayList();
        String region = getRegion(clientConfig);
        String[] availZones = clientConfig.getAvailabilityZones(clientConfig.getRegion());
        if (availZones == null || availZones.length == 0) {
            availZones = new String[]{"default"};
        }

        logger.debug("The availability zone for the given region {} are {}", region, availZones);
        int myZoneOffset = getZoneOffset(instanceZone, preferSameZone, availZones);
        List<String> serviceUrls = clientConfig.getEurekaServerServiceUrls(availZones[myZoneOffset]);
        if (serviceUrls != null) {
            orderedUrls.addAll(serviceUrls);
        }

        int currentOffset = myZoneOffset == availZones.length - 1 ? 0 : myZoneOffset + 1;

        while(currentOffset != myZoneOffset) {
            serviceUrls = clientConfig.getEurekaServerServiceUrls(availZones[currentOffset]);
            if (serviceUrls != null) {
                orderedUrls.addAll(serviceUrls);
            }

            if (currentOffset == availZones.length - 1) {
                currentOffset = 0;
            } else {
                ++currentOffset;
            }
        }

        if (orderedUrls.size() < 1) {
            throw new IllegalArgumentException("DiscoveryClient: invalid serviceUrl specified!");
        } else {
            return orderedUrls;
        }
    }

Region Zone
在上面的函数中,可以发现,客户端一次加载了两个内容,第一个是Region,第二个是Zone,从其加载逻辑上我们可以判断它们之间的关系:

  • 通过getRegion函数,我们可以看到它从配置中读取了一个Region返回,所以一个微服务应用只可以属于一个Region,如果不特别配置,默认为default。若我们要自己设置,可以通过eureka.client.region属性来定义。
public static String getRegion(EurekaClientConfig clientConfig) {
        String region = clientConfig.getRegion();
        if (region == null) {
            region = "default";
        }

        region = region.trim().toLowerCase();
        return region;
    }
  • 通过getAvailabilityZones函数,可以知道当我们没有特别为Region配置Zone的时候,将默认采用defaultZone,这也是我们之前配置参数eureka.client.serviceUrl.defaultZone的由来。若要为应用指定Zone,可以通过eureka.client.availability-zones属性来进行设置。从该函数的return内容,我们可以知道Zone能设置多个,并且通过逗号分隔来配置。由此,我们可以判断Region与Zone是一对多的关系。

getAvailabilityZones函数的具体实现是EurekaClientConfig接口的实现类DefaultEurekaClientConfig类的getAvailabilityZones函数如下:

public String[] getAvailabilityZones(String region) {
        return this.configInstance.getStringProperty(this.namespace + region + "." + "availabilityZones", "defaultZone").get().split(",");
    }

eureka源码未完待续!!!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值