⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://www.iocoder.cn/Eureka/eureka-client-init-second/ 「芋道源码」欢迎转载,保留摘要,谢谢!

本文主要基于 Eureka 1.8.X 版本


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

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 书籍

2. EurekaClientConfig

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

2.1 类关系图

EurekaClientConfig 整体类关系如下图:

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

2.2 配置属性

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

  • Region、Zone 相关
    • #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;
      }

      • x
    • 进步一步理解 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 获取注册信息相关
    • #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);
}
}

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 小结

推荐参考阅读:

3. EurekaTransportConfig

3.1 类关系图

EurekaTransportConfig 整体类关系如下图:

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

3.2 配置属性

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

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

666. 彩蛋

知识星球

涉及到配置,内容初看起来会比较多,慢慢理解后,就会变得很“啰嗦”,请保持耐心。

胖友,分享一个朋友圈可好。

文章目录
  1. 1. 1. 概述
  2. 2. 2. EurekaClientConfig
    1. 2.1. 2.1 类关系图
    2. 2.2. 2.2 配置属性
    3. 2.3. 2.3 DefaultEurekaClientConfig
    4. 2.4. 2.4 DefaultEurekaClientConfigProvider
    5. 2.5. 2.5 小结
  3. 3. 3. EurekaTransportConfig
    1. 3.1. 3.1 类关系图
    2. 3.2. 3.2 配置属性
    3. 3.3. 3.3 DefaultEurekaTransportConfig
  4. 4. 666. 彩蛋