注册中心 Eureka 源码解析 —— Eureka-Client 初始化(二)之 EurekaClientConfig

1. 概述

本文接《Eureka 源码解析 —— Eureka-Client 初始化(一)之 EurekaInstanceConfig》,主要分享 Eureka-Client 自身初始化的过程的第二部分 —— EurekaClientConfig,不包含 Eureka-Client 向 Eureka-Server 的注册过程( ?后面会另外文章分享 )。

Eureka-Client 自身初始化过程中,涉及到主要对象如下图:

  1. 创建 EurekaInstanceConfig对象
  2. 使用 EurekaInstanceConfig对象 创建 InstanceInfo对象
  3. 使用 EurekaInstanceConfig对象 + InstanceInfo对象 创建 ApplicationInfoManager对象
  4. 创建 EurekaClientConfig对象
  5. 使用 ApplicationInfoManager对象 + EurekaClientConfig对象 创建 EurekaClient对象

考虑到整个初始化的过程中涉及的配置特别多,拆分成三篇文章:

  1. (一)EurekaInstanceConfig)
  2. 【本文】(二)EurekaClientConfig
  3. (三)EurekaClient

下面我们来看看每个的实现。

推荐 Spring Cloud 书籍

  • 请支持正版。下载盗版,等于主动编写低级 BUG
  • 程序猿DD —— 《Spring Cloud微服务实战》
  • 周立 —— 《Spring Cloud与Docker微服务架构实战》
  • 两书齐买,京东包邮。

2. EurekaClientConfig

com.netflix.discovery.EurekaClientConfigEureka-Client 配置接口

2.1 类关系图

EurekaClientConfig 整体类关系如下图:

  • 本文只解析红圈部分类。
  • EurekaArchaius2ClientConfig 基于 Netflix Archaius 2.x 实现,目前还在开发中,因此暂不解析。

2.2 配置属性

点击 EurekaClientConfig 查看配置属性简介,已经添加中文注释,可以对照着英文注释一起理解。这里笔者摘出部分较为重要的属性:

  • Region、Zone 相关
    • x
    • #getRegion() :Eureka-Client 所在区域( region )。
    • #getAvailabilityZones() :Eureka-Client 所在地区( region ) 可用区( zone )集合。该参数虽然是数组,第一个元素代表其所在的可用区。实现代码如下: // InstanceInfo.java public static String getZone(String[] availZones, InstanceInfo myInfo) { String instanceZone = ((availZones == null || availZones.length == 0) ? "default" : availZones[0]); if (myInfo != null && myInfo.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon) { String awsInstanceZone = ((AmazonInfo) myInfo.getDataCenterInfo()) .get(AmazonInfo.MetaDataKey.availabilityZone); if (awsInstanceZone != null) { instanceZone = awsInstanceZone; } } return instanceZone; }
  • 进步一步理解 Region、Zone 查看《周立 —— Region、Zone解析》。
  • 使用 DNS 获取 Eureka-Server URL 相关
    • #shouldUseDnsForFetchingServiceUrls() :是否使用 DNS 方式获取 Eureka-Server URL 地址。
    • #getEurekaServerDNSName() :Eureka-Server 的 DNS 名。
    • #getEurekaServerPort() :Eureka-Server 的端口。
    • #getEurekaServerURLContext() :Eureka-Server 的 URL Context 。
    • #getEurekaServiceUrlPollIntervalSeconds() :轮询获取 Eureka-Server 地址变更频率,单位:秒。默认:300 秒。
    • #shouldPreferSameZoneEureka() :优先使用相同区( zone )的 Eureka-Server。
  • 直接配合 Eureka-Server URL 相关
    • #getEurekaServerServiceUrls() : Eureka-Server 的 URL 集合。
  • 发现:从 Eureka-Server 获取注册信息相关
    • 实现逻辑和 《Eureka 源码解析 —— 应用实例注册发现 (六)之全量获取》
    • 本系列暂时写对它的源码解析,感兴趣的同学可以看 com.netflix.discovery.shared.transport.EurekaHttpClient#getVip(String, String...)com.netflix.eureka.resources.AbstractVIPResource
    • #shouldFetchRegistry() :是否从 Eureka-Server 拉取注册信息。
    • #getRegistryFetchIntervalSeconds() :从 Eureka-Server 拉取注册信息频率,单位:秒。默认:30 秒。
    • #shouldFilterOnlyUpInstances() :是否过滤,只获取状态为开启( Up )的应用实例集合。
    • #fetchRegistryForRemoteRegions() :TODO[0009]:RemoteRegionRegistry
    • #getCacheRefreshExecutorThreadPoolSize() :注册信息缓存刷新线程池大小。
    • #getCacheRefreshExecutorExponentialBackOffBound() :注册信息缓存刷新执行超时后的延迟重试的时间。
    • #getRegistryRefreshSingleVipAddress() :只获得一个 vipAddress 对应的应用实例们的注册信息。
  • 注册:向 Eureka-Server 注册自身服务
    • #shouldRegisterWithEureka() :是否向 Eureka-Server 注册自身服务。
    • #shouldUnregisterOnShutdown() :是否向 Eureka-Server 取消注册自身服务,当进程关闭时。
    • #getInstanceInfoReplicationIntervalSeconds() :向 Eureka-Server 同步应用实例信息变化频率,单位:秒。
    • #getInitialInstanceInfoReplicationIntervalSeconds() :向 Eureka-Server 同步应用信息变化初始化延迟,单位:秒。
    • #getBackupRegistryImpl() :获取备份注册中心实现类。当 Eureka-Client 启动时,无法从 Eureka-Server 读取注册信息(可能挂了),从备份注册中心读取注册信息。目前 Eureka-Client 未提供合适的实现。
    • #getHeartbeatExecutorThreadPoolSize() :心跳执行线程池大小。
    • #getHeartbeatExecutorExponentialBackOffBound() :心跳执行超时后的延迟重试的时间。

2.3 DefaultEurekaClientConfig

com.netflix.discovery.DefaultEurekaClientConfig,基于配置文件Eureka-Client 配置实现类,实现代码如下:

public class DefaultEurekaClientConfig implements EurekaClientConfig {

    public static final String DEFAULT_ZONE = "defaultZone";

    /**
     * 命名空间
     */
    private final String namespace;
    /**
     * 配置文件对象
     */
    private final DynamicPropertyFactory configInstance;
    /**
     * HTTP 传输配置
     */
    private final EurekaTransportConfig transportConfig;

    public DefaultEurekaClientConfig(String namespace) {
        // 设置 namespace,为 "." 结尾
        this.namespace = namespace.endsWith(".")
                ? namespace
                : namespace + ".";
        // 初始化 配置文件对象
        this.configInstance = Archaius1Utils.initConfig(CommonConstants.CONFIG_FILE_NAME);
        // 创建 HTTP 传输配置
        this.transportConfig = new DefaultEurekaTransportConfig(namespace, configInstance);
    }
}
  • 类似 PropertiesInstanceConfig,点击《Eureka 源码解析 —— Eureka-Client 初始化(一)之 EurekaInstanceConfig》「2.4 PropertiesInstanceConfig」查看详细解析。
  • com.netflix.discovery.PropertyBasedClientConfigConstants 可以看到配置文件的每个属性 KEY 。
  • transportConfig 属性,在 「3. EurekaTransportConfig」 详细解析。

2.4 DefaultEurekaClientConfigProvider

com.netflix.discovery.providers.DefaultEurekaClientConfigProvider,创建 DefaultEurekaClientConfig 的工厂,实现代码如下:

public class DefaultEurekaClientConfigProvider implements Provider<EurekaClientConfig> {

    @Inject(optional = true)
    @EurekaNamespace
    private String namespace;

    private DefaultEurekaClientConfig config;

    @Override
    public synchronized EurekaClientConfig get() {
        if (config == null) {
            config = (namespace == null)
                    ? new DefaultEurekaClientConfig()
                    : new DefaultEurekaClientConfig(namespace);

            // TODO: Remove this when DiscoveryManager is finally no longer used
            DiscoveryManager.getInstance().setEurekaClientConfig(config);
        }

        return config;
    }
}

2.5 小结

推荐参考阅读:

  • 程序猿DD —— 《Spring Cloud微服务实战》 Spring Cloud Eureka —— 配置详解
  • 风中程序猿 —— 《微服务架构:Eureka参数配置项详解》

3. EurekaTransportConfig

3.1 类关系图

EurekaTransportConfig 整体类关系如下图:

  • 本文只解析红圈部分类。
  • EurekaArchaius2TransportConfig 基于 Netflix Archaius 2.x 实现,目前还在开发中,因此暂不解析。

3.2 配置属性

点击 EurekaTransportConfig 查看配置属性简介,已经添加中文注释,可以对照着英文注释一起理解。这里笔者摘出部分较为重要的属性:

  • #getSessionedClientReconnectIntervalSeconds() :EurekaHttpClient 会话周期性重连时间,单位:秒。在 《Eureka 源码解析 —— 网络通信》「5.4 SessionedEurekaHttpClient」》 有详细解析。
  • #getRetryableClientQuarantineRefreshPercentage() :重试 EurekaHttpClient ,请求失败的 Eureka-Server 隔离集合占比 Eureka-Server 全量集合占比,超过该比例,进行清空。在 《Eureka 源码解析 —— 网络通信》「5.3 RetryableEurekaHttpClient」》 有详细解析。
  • 异步 EndPoint 集群解析器
    • 在 《Eureka 源码解析 —— EndPoint 与 解析器》「3.6 AsyncResolver」》 有详细解析。
    • #getAsyncResolverRefreshIntervalMs() :异步解析 EndPoint 集群频率,单位:毫秒。
    • #getAsyncResolverWarmUpTimeoutMs() :异步解析器预热解析 EndPoint 集群超时时间,单位:毫秒。
    • #getAsyncExecutorThreadPoolSize() :异步解析器线程池大小。
  • TODO[0028]:写入集群和读取集群。Eureka 2.x 兼容 :
    • #getApplicationsResolverDataStalenessThresholdSeconds()
    • #applicationsResolverUseIp()
    • #getWriteClusterVip()
    • #getReadClusterVip()
    • #getBootstrapResolverStrategy()
    • #useBootstrapResolverForQuery()

3.3 DefaultEurekaTransportConfig

com.netflix.discovery.shared.transport.DefaultEurekaTransportConfig,基于配置文件网络传输配置实现类,实现代码如下:

public class DefaultEurekaTransportConfig implements EurekaTransportConfig {

    private static final String SUB_NAMESPACE = TRANSPORT_CONFIG_SUB_NAMESPACE + ".";

    /**
     * 命名空间
     */
    private final String namespace;
    /**
     * 配置文件对象
     */
    private final DynamicPropertyFactory configInstance;

    public DefaultEurekaTransportConfig(String parentNamespace, DynamicPropertyFactory configInstance) {
        // 命名空间
        this.namespace = parentNamespace == null
                ? SUB_NAMESPACE
                : (parentNamespace.endsWith(".")
                    ? parentNamespace + SUB_NAMESPACE
                    : parentNamespace + "." + SUB_NAMESPACE);
        // 配置文件对象
        this.configInstance = configInstance;
    }
}
  • 类似 PropertiesInstanceConfig,点击《Eureka 源码解析 —— Eureka-Client 初始化(一)之 EurekaInstanceConfig》「2.4 PropertiesInstanceConfig」查看详细解析。
  • com.netflix.discovery.shared.transport.PropertyBasedTransportConfigConstants 可以看到配置文件的每个属性 KEY 。

原文发布于微信公众号 - 芋道源码(YunaiV)

原文发表时间:2018-03-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT笔记

SpringBoot开发案例之奇技淫巧

spring-boot-starter-parent包含了大量配置好的依赖管理,在自己项目添加这些依赖的时候不需要写<version>版本号

40060
来自专栏携程技术中心

干货 | 深度剖析服务发现组件Netflix Eureka

作者简介 宋顺,携程框架研发部技术专家。2016年初加入携程,主要负责中间件产品的相关研发工作。毕业于复旦大学软件工程系,曾就职于大众点评,担任后台系统技术负责...

48250
来自专栏决胜机器学习

SpringBoot工作机制

SpringBoot工作机制 (原创内容,转载请注明来源,谢谢) 一、概述 Spring Boot是对于Spring框架“约定优于配置”理念的实践产物。 一个最...

43060
来自专栏Ryan Miao

Ubuntu安装Java8和Java9

前言 系统:Ubuntu 16.04 软件: Java8, Java9 Tips: Java 9 的代码由于提供了新特性,所以有些代码并不支持向后兼容。也就...

42880
来自专栏Java 源码分析

SpringBoot 笔记 ( 一 ):启动流程

SpringBoot 笔记(一): 启动流程 1. 配置开发环境 1. 创建 Maven 项目 然后我们首先在项目里面加上编译环境,防止每一次更新 Maven ...

32240
来自专栏熊二哥

Spring快速入门

Spring源码剖析一书,非常细致,但对于个人来说,意义不算特别的大,因此选其可用部分做个记录就好。 ? 功能 示例 配置文件的解析...

192100
来自专栏开发与安全

linux系统编程之文件与I/O(五):文件的内核结构file和dup实现重定向

一、打开文件内核数据结构 1、一个进程打开两个文件 ? 文件状态标志:读、写、追加、同步、非阻塞等 2、一个进程两次打开同一文件 ? 3、两个进程打开同一文...

23990
来自专栏微信公众号:Java团长

教你理清SpringBoot与SpringMVC的关系

spring boot就是一个大框架里面包含了许许多多的东西,其中spring就是最核心的内容之一,当然就包含spring mvc。spring mvc 是只是...

22840
来自专栏Java架构

教你理清SpringBoot与SpringMVC的关系

spring boot就是一个大框架里面包含了许许多多的东西,其中spring就是最核心的内容之一,当然就包含spring mvc。spring mvc 是只是...

15930
来自专栏子勰随笔

在Linux服务器(ubuntu 16)上部署多套PHP环境

29160

扫码关注云+社区

领取腾讯云代金券