[享学Eureka] 四、Eureka配置之:EurekaClientConfig客户端配置

编程是一种单调的生活,因此程序员比普通人需要更多的关怀,更多的友情。

–> 返回专栏总目录 <–
代码下载地址:https://github.com/f641385712/netflix-learning

前言

接着上文介绍完EurekaInstanceConfig对于实例的配置后,本文继续介绍对Client客户端的配置接口:EurekaClientConfig。他两者将共同为EurekaClient的初始化提供基础数据支持。


正文

不同于EurekaInstanceConfig的是,EurekaClientConfig属于客户端配置,Server端肯定是不会用的。它控制着Client端去连接、获取Server端信息的一些行为,比如获取频次、全量or增量、超时时间等等。


EurekaClientConfig

Eureka-Client配置接口,用于给Eureka-Server注册实例。先做个心理准备:该接口有50+个接口方法~~~

不瞒你说,貌似是我活这么大见过的“最大”接口~

// 它仅有一个内置实现,便是这个实现。在Guice里就是它喽
@ImplementedBy(DefaultEurekaClientConfig.class)
public interface EurekaClientConfig {

	// 从 Eureka-Server 拉取注册信息频率。默认值是30s
	// 它决定了Eureka Client端TimedSupervisorTask#CacheRefreshThread任务的执行频率
	int getRegistryFetchIntervalSeconds();
	
	// Replication:赋值,回响
	// 更新实例信息的变化到Eureka服务端的间隔时间,默认值30s
	// 使用InstanceInfoReplicator上传InstanceInfo信息,定时执行
	int getInstanceInfoReplicationIntervalSeconds();
	// 执行上面任务的初始化Delay延迟  默认值40s
	int getInitialInstanceInfoReplicationIntervalSeconds();

	// 去Server端获取到所有的ServiceUrl集群地址的时间间隔,默认是5分钟
	// 我们配置ServiceUrl时只需要配置一个就能拿到所有,靠的就是它定时去轮询
	// 因为ServiceUrl一般都不会有变化,所以此轮询时间间隔长点是木有关系的~~~
	// 当然若你需要动态更新ServiceUrl,那么此值就起作用喽~~~~
	int getEurekaServiceUrlPollIntervalSeconds();


	// 各种代理相关.... 略
	String getProxyHost();
	String getProxyPort();
	String getProxyUserName();
	String getProxyPassword();

	// 是否要对发送请求的内容进行GZip压缩 默认值是true
	// true:会添加一个jersey的过滤器GZIPContentEncodingFilter在发送请求之前加个请求头:`Accept-Encoding:gzip`
	boolean shouldGZipContent();
	
	// 控制发送请求时的readTimeout值  默认是8s
	// 比如默认使用Jersey的话,那就是控制它的读取超时时间喽
	int getEurekaServerReadTimeoutSeconds();
	// 同上,控制connectionTimeout 默认是5s
	int getEurekaServerConnectTimeoutSeconds();
	
	// 获取备注册中心的实现类(若你的EurekaClient链接的Server挂了,就使用它去连其它的)
	// 若你想做兜底,那么可以使用它(比如使用Nacos做备用)
	// 说明:内部并未提供任何实现,若有需要请自己提供实现类,且配置好就可生效
	String getBackupRegistryImpl();

	// =========毕竟Client端是可以并发发出N多个请求请求Server端的=========
	// =========这里就给出了限制,避免单个Client实例把Server端就给搞垮了===========
	// 控制maxTotalConnections,也就是发送请求的连接池的最大容量  默认值200
	// 如果是Apache的HC,那就是控制它的连接池大小
	int getEurekaServerTotalConnections();
	// 单台host的允许的连接总数  默认值50
	int getEurekaServerTotalConnectionsPerHost();
	
	// ==========下面这些配置均只有在eureka服务器ip地址列表是在DNS中**才会用到**,默认为null========
	// 表示eureka注册中心的路径,如果配置为eureka,则为http://x.x.x.x:x/eureka/
	// 在eureka的配置文件中加入此配置表示eureka作为客户端向注册中心注册,从而构成eureka集群
	String getEurekaServerURLContext();
	// 获取eureka服务器的端口
	String getEurekaServerPort();
	// 获取要查询的DNS名称来获得eureka服务器
	String getEurekaServerDNSName();

	// 是否使用 DNS 方式获取 Eureka-Server URL 地址  默认是false
	// 在获取到Server集群的节点后,会解析出url们。这里决定如何解析(要不要用DNS)
	boolean shouldUseDnsForFetchingServiceUrls();

	// (重要)是否注册自己这个实例到Server上  默认是true
	// 一般来说,如果你自己就是Server端,可以不用注册上去的,没有必要~~~~
	// 如果不注册自己,很多定时任务是不需要的,因此Server端建议关闭此项
	// 当然你若想看看自己是否还“活着”,让其注册上去也无妨
	boolean shouldRegisterWithEureka();
	// 很明显这应该为true嘛。
	// 它是在EurekaClient#shutdown方法里被调用的,@PreDestroy也促发哦
	// 那么。。。kill -9 它会执行麽??? 这个问题留给你
    default boolean shouldUnregisterOnShutdown() {
        return true;
    }	

	// 实例是否使用同一zone里的eureka服务器,默认为true
	// 理想状态下,eureka客户端与服务端是在同一zone下
	boolean shouldPreferSameZoneEureka();
	// 简单的说:是否允许Server端给你返回302重定向其它机器去处理(比如自己负载太高了不想处理)~~~
	// 它的实现方式是发送请求时添加请求头:`X-Discovery-AllowRedirect:true`
	// 默认值是false哦~
	boolean allowRedirects();
	// 当Client本地的实例们和Server返回的实例们出现差时(比如状态变更、元数据变更等),是否记录log日志
	// 默认值是false,不记录。毕竟这种日志意义并不大~~~没必要消耗性能
	boolean shouldLogDeltaDiff();
	// 是否禁用增量获取   true:每次全量获取   false:每次增量获取
	// 默认值是false
	boolean shouldDisableDelta();
	
	// 该属性一般很少用。只有dataCenterInfo是Amazon的时候,才用到。
	// 而我们默认的dataCenterInfo是MyOwn,因此也用不上这个属性。
	// 另外它需要结合配置对应remote region的availability-zones一起使用才行
    @Nullable
    String fetchRegistryForRemoteRegions();
    // 获取实例所在的Region,AWS中使用。默认值是us-east-1
    String getRegion();
    // zone,一个region中有多个zone.可以配置多个值,中间使用逗号分隔。
    String[] getAvailabilityZones(String region);
	// Eureka-Server 的 URL 集合
	// 默认为http://XXXX:X/eureka/,但是如果采用DNS方式获取服务地址,则不需要配置此设置。
    List<String> getEurekaServerServiceUrls(String myZone);

	// 获取实例时是否过滤,仅保留UP状态的实例  默认值是true
    boolean shouldFilterOnlyUpInstances();
    // 控制连接线程池的。最大空闲时间就断开喽~   默认值30s
    int getEurekaConnectionIdleTimeoutSeconds();
    // 是否从Eureka服务端获取注册信息  默认true
    // 比如是true啊  不然你Client干嘛来了呢?
    boolean shouldFetchRegistry();
    // 只去只获得一个 vipAddress 对应的应用实例们的注册信息。默认值null
    // 若指定来该值:那么只会从这个单一的vipAddress里获取
    @Nullable
    String getRegistryRefreshSingleVipAddress();
    
    
    // 心跳执行程序(续约线程)线程池的大小   默认为5
    int getHeartbeatExecutorThreadPoolSize();
    // 心跳超时重试延迟时间的最大乘数值。默认值是10
    // 也就是超时了的话  5*10  50s后再去试一把
    int getHeartbeatExecutorExponentialBackOffBound();
    // 缓存刷新线程池的初始化线程数  默认值5
    int getCacheRefreshExecutorThreadPoolSize();
    // 不解释。 默认值10
    int getCacheRefreshExecutorExponentialBackOffBound();

	// eureka服务器序列化/反序列化的信息中获取“$”符号的的替换字符串。默认为“_-”
    String getDollarReplacement();
    // eureka服务器序列化/反序列化的信息中获取“_”符号的的替换字符串。默认为“__”
    String getEscapeCharReplacement();

	// true:通过ApplicationInfoManager本地实例状态时,立即触发更新到远程server
	// false:不立即触发 依赖于心跳
	// 默认值true
    boolean shouldOnDemandUpdateStatusChange();
    // 客户端是否应在初始化期间强制注册  默认值false
    // 毕竟初始化期间不一定全部搞定了,所以为false较好
    default boolean shouldEnforceRegistrationAtInit() {
        return false;
    }

	// 临时配置,一旦最新的编解码器稳定,就可以删除
	// 显然,现在已经无用了~~~~
    String getEncoderName();
    String getDecoderName();

	// 加上请求头:`X-Eureka-Accept = xxx`
	// 可选值是:full/compact
    String getClientDataAccept();
    // experimental:试验的
    // 当尝试新功能迁移过程时,为了避免配置API污染,试验的这部分配置即可通过此接口传递
    // 可见:JerseyEurekaHttpClientFactory#buildExperimental用于构建试验的配置
    // 用于灰度一些实验性的配置比较好用~~~~~
    String getExperimental(String name);
    
    
	// 为了兼容性,返回传输层配置类
	// EurekaTransportConfig会放在详解传输的时候解析
	// 也是在DiscoveryClient里会使用到~~~~~~~
    EurekaTransportConfig getTransportConfig();
}

EurekaClientConfig作为客户端的配置,涉及的范围还是颇广的。最主要的当属EurekaClient(实际为DiscoveryClient)实例的使用,还会有序列化、编解码器、集群节点的获取等等均会使用到它配置的值。

该配置接口默认有且仅有一个实现类:DefaultEurekaClientConfig


DefaultEurekaClientConfig 基于配置文件的默认实现

默认实现,一切值均来自于Archaius管理的配置文件,也就是主配置以及eureka-client.properties里的内容。

@Singleton
@ProvidedBy(DefaultEurekaClientConfigProvider.class)
public class DefaultEurekaClientConfig implements EurekaClientConfig {
	
    public static final String DEFAULT_ZONE = "defaultZone";
    // 多个zone之间以逗号分隔
    public static final String URL_SEPARATOR = "\\s*,\\s*";
    // 默认值是eureka
    private final String namespace;
    // 默认挂历主配置以及`eureka-client.properties`这种配置文件
    private final DynamicPropertyFactory configInstance;
    // 实例是DefaultEurekaTransportConfig
    private final EurekaTransportConfig transportConfig;

	// 配置所属的region。
	// eureka.region = xxx。默认值是us-east-1
    @Override
    public String getRegion() {
        DynamicStringProperty defaultEurekaRegion = configInstance.getStringProperty(CLIENT_REGION_FALLBACK_KEY, Values.DEFAULT_CLIENT_REGION);
        return configInstance.getStringProperty(namespace + CLIENT_REGION_KEY, defaultEurekaRegion.get()).get();
    }
	// 若你没配置eureka.[region].availabilityZones = xxx的值(可配置多个)
	// region的值一般来自于`getRegion`方法的返回值
	// 那默认值就是defaultZone。绝大部分情况下,我们使用defaultZone就好
    @Override
    public String[] getAvailabilityZones(String region) {
        return configInstance.getStringProperty(
                        namespace + region + "." + CONFIG_AVAILABILITY_ZONE_PREFIX,
                        DEFAULT_ZONE).get().split(URL_SEPARATOR);
    }
    // 获取指定zone下的ServiceUrls们~~~  这三个方法一层包一层有木有
    // eureka.serviceUrl.[myZone] = xxx(大部分情况是:eureka.serviceUrl.defaultZone = xxx)
    // 若上面按照zone木有找到,找这个key: eureka.serviceUrl.default = xxx
    // 均可以用逗号分隔配置多个哦~~~~~
    @Override
    public List<String> getEurekaServerServiceUrls(String myZone) {
        String serviceUrls = configInstance.getStringProperty(namespace + CONFIG_EUREKA_SERVER_SERVICE_URL_PREFIX + "." + myZone, null).get();
        if (serviceUrls == null || serviceUrls.isEmpty()) {
            serviceUrls = configInstance.getStringProperty(namespace + CONFIG_EUREKA_SERVER_SERVICE_URL_PREFIX + ".default", null).get();
        }
        if (serviceUrls != null) {
            return Arrays.asList(serviceUrls.split(URL_SEPARATOR));
        }

        return new ArrayList<String>();
    }


	// eureka.client.refresh.interval = xxx
    @Override
    public int getRegistryFetchIntervalSeconds() {
        return configInstance.getIntProperty(namespace + REGISTRY_REFRESH_INTERVAL_KEY, 30).get();
    }
    ...
    // 默认值是5分钟去轮询一次  足够了
    @Override
    public int getEurekaServiceUrlPollIntervalSeconds() {
        return configInstance.getIntProperty(namespace + EUREKA_SERVER_URL_POLL_INTERVAL_KEY, 5 * 60 * 1000).get() / 1000;
    }
	...
    @Override
    public EurekaTransportConfig getTransportConfig() {
        return transportConfig;
    }
}

对于默认实现,有如下注意事项:

扫描二维码关注公众号,回复: 10283652 查看本文章
  • getRegion()方法用于指定当前实例所在的区域,若没配置默认值是us-east-1。你可以使用eureka.region = xxx来指定
  • String[] getAvailabilityZones(String region)获取指定区域的可用区们,若没配置默认值是defaultZone。你可以通过eureka.传入的region值.availabilityZones = xxx来配置(可够好分隔指定多个)
    • 针对不同的region可以配置多份
  • List<String> getEurekaServerServiceUrls(String myZone):获取可用区里的ServiceUrls们。最终我们都是希望得到一个url嘛,就是通过此方法来获取。取值自:eureka.serviceUrl.传入的myZone值 = xxx,xxx,xxx / 兜底的eureka.serviceUrl.default = xxx,xxx,xxx(优先级从前向后)
    • 针对不同的zone可以配置多份
    • 该值是必须配置指定的,否则连不上Server端(当然你不往server端注册就不需要配置喽)
    • 绝大部分情况下我们使用一个zone,也就是defaultZone即可。那配置就为:eureka.serviceUrl.defaultZone = xxx,xxx,xxx / 兜底的eureka.serviceUrl.default = xxx,xxx,xxx
      • 此处特别注意:Spring Cloud下是不支持兜底方案eureka.serviceUrl.default = xxx,xxx,xxx这种方式的,只支持前者也就是defaultZone方式~
  • Spring Cloud配置和源生配置是不一样的
    • SC下配置均以eureka.instance、eureka.client、eureka.client.transport开头
      • SC自己增加了一些配置如常用的:eureka.instance.preferIpAddress = true等,这在讲解SC整合的时候会说出更多区别
    • 源生Eureka均是以eureka开头即可(当然命名空间可改,但只要不冲突谁会改呢?对吧)

另外,在Guice下该接口实例DefaultEurekaClientConfig是由DefaultEurekaClientConfigProvider来提供的,而在SC下它的实例是DefaultEurekaClientConfigBean由Spring来负责提供。


总结

关于Eureka配置之:EurekaClientConfig客户端配置就介绍到这了,关于Eureka最最最重要的两大配置项EurekaInstanceConfigEurekaClientConfig就介绍完了,一个属性不落的都给与了“充分”的说明,同样的可以作为字典在工作中做参阅使用。

当然,它还有一个配置类EurekaTransportConfig,它相对来说没那么的重要(主要是我们一般都不会配置),在下文将继续介绍。

分隔线

声明

原创不易,码字不易,多谢你的点赞、收藏、关注。把本文分享到你的朋友圈是被允许的,但拒绝抄袭。你也可【左边扫码/或加wx:fsx641385712】邀请你加入我的 Java高工、架构师 系列群大家庭学习和交流。
往期精选

发布了370 篇原创文章 · 获赞 548 · 访问量 49万+

猜你喜欢

转载自blog.csdn.net/f641385712/article/details/105128652