主頁 > 後端開發 > Eureka多節點資料不同步問題

Eureka多節點資料不同步問題

2022-06-15 20:46:48 後端開發

前言

學習eureka的程序中,配置了本地多節點,發現節點間資料不同步,自己找原始碼發現eureka.client.service-url.default-zone 配置有誤,default-zone應該為defaultZone,該配置配置在EurekaClientConfigBean中,如果未配置defaultZone,默認取http://localhost:8761/eureka/,下邊為原始碼部分截圖
image

以下為找到問題后搜到的文章,這里做下記錄,如果解決了您的問題可以為原位作者點贊


以下為原文 轉載自joshua317博客 Spring Boot-yaml格式,eureka客戶端配置default-zone報錯問題 - joshua317的博客

一、問題

在配置eureka客戶端的時候,設定好eureka客戶端的簡單配置,配置如下:

server:
  port: 8081
  error:
    path: ./logs/error
eureka:
  client:
    service-url:
      default-zone: http://eureka.joshua317.com/eureka/

結果運行后,報了以下錯誤:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.5)
 
2021-09-29 15:55:00.825  INFO 12672 --- [           main] com.joshua317.demo.DemoApplication       : Starting DemoApplication using Java 1.8.0_281 on joshua with PID 12672 (E:\java\demo\target\classes started by joshua317 in E:\java\demo)
2021-09-29 15:55:00.827  INFO 12672 --- [           main] com.joshua317.demo.DemoApplication       : The following profiles are active: dev
2021-09-29 15:55:01.465  INFO 12672 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=77e68b99-4210-3ba6-ae6f-308380a46828
2021-09-29 15:55:01.696  INFO 12672 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8081 (http)
2021-09-29 15:55:01.705  INFO 12672 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-09-29 15:55:01.706  INFO 12672 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.53]
2021-09-29 15:55:01.829  INFO 12672 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-09-29 15:55:01.829  INFO 12672 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 966 ms
2021-09-29 15:55:05.597  INFO 12672 --- [           main] DiscoveryClientOptionalArgsConfiguration : Eureka HTTP Client uses RestTemplate.
2021-09-29 15:55:08.935  WARN 12672 --- [           main] iguration$LoadBalancerCaffeineWarnLogger : Spring Cloud LoadBalancer is currently working with the default cache. You can switch to using Caffeine cache, by adding it and org.springframework.cache.caffeine.CaffeineCacheManager to the classpath.
2021-09-29 15:55:08.991  INFO 12672 --- [           main] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
2021-09-29 15:55:09.020  INFO 12672 --- [           main] com.netflix.discovery.DiscoveryClient    : Initializing Eureka in region us-east-1
2021-09-29 15:55:09.024  INFO 12672 --- [           main] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2021-09-29 15:55:09.049  INFO 12672 --- [           main] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
2021-09-29 15:55:09.049  INFO 12672 --- [           main] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
2021-09-29 15:55:09.050  INFO 12672 --- [           main] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
2021-09-29 15:55:09.050  INFO 12672 --- [           main] com.netflix.discovery.DiscoveryClient    : Application is null : false
2021-09-29 15:55:09.050  INFO 12672 --- [           main] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
2021-09-29 15:55:09.050  INFO 12672 --- [           main] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
2021-09-29 15:55:09.050  INFO 12672 --- [           main] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server
2021-09-29 15:55:15.705  INFO 12672 --- [           main] c.n.d.s.t.d.RedirectingEurekaHttpClient  : Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://localhost:8761/eureka/}, exception=I/O error on GET request for "http://localhost:8761/eureka/apps/": Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect stacktrace=org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8761/eureka/apps/": Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:785)
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
	at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:602)
	at org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient.getApplicationsInternal(RestTemplateEurekaHttpClient.java:145)
	at org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient.getApplications(RestTemplateEurekaHttpClient.java:135)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)
	at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.executeOnNewServer(RedirectingEurekaHttpClient.java:121)
	at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.execute(RedirectingEurekaHttpClient.java:80)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)
	at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:120)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)
	at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)
	at com.netflix.discovery.DiscoveryClient.getAndStoreFullRegistry(DiscoveryClient.java:1101)
	at com.netflix.discovery.DiscoveryClient.fetchRegistry(DiscoveryClient.java:1014)
	at com.netflix.discovery.DiscoveryClient.<init>(DiscoveryClient.java:441)
	at com.netflix.discovery.DiscoveryClient.<init>(DiscoveryClient.java:283)
	at com.netflix.discovery.DiscoveryClient.<init>(DiscoveryClient.java:279)
	at org.springframework.cloud.netflix.eureka.CloudEurekaClient.<init>(CloudEurekaClient.java:66)
	at org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration.eurekaClient(EurekaClientAutoConfiguration.java:295)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:374)
	at org.springframework.cloud.context.scope.GenericScope$BeanLifecycleWrapper.getBean(GenericScope.java:376)
	at org.springframework.cloud.context.scope.GenericScope.get(GenericScope.java:179)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:371)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)
	at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration.getTargetObject(EurekaRegistration.java:127)
	at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration.getEurekaClient(EurekaRegistration.java:115)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
	at org.springframework.cloud.context.scope.GenericScope$LockedScopedProxyFactoryBean.invoke(GenericScope.java:485)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
	at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration$$EnhancerBySpringCGLIB$$dd5063c0.getEurekaClient(<generated>)
	at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry.maybeInitializeClient(EurekaServiceRegistry.java:54)
	at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry.register(EurekaServiceRegistry.java:38)
	at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration.start(EurekaAutoServiceRegistration.java:83)
	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178)
	at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54)
	at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356)
	at java.lang.Iterable.forEach(Iterable.java:75)
	at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155)
	at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123)
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:338)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332)
	at com.joshua317.demo.DemoApplication.main(DemoApplication.java:10)
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:156)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
	at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
	at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
	at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:776)
	... 68 more
Caused by: java.net.ConnectException: Connection refused: connect
	at java.net.DualStackPlainSocketImpl.connect0(Native Method)
	at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:162)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394)
	at java.net.Socket.connect(Socket.java:606)
	at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75)
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
	... 81 more

看了下報錯資訊,主要原因是沒有獲取到配置里面的eureka服務eureka.service-url,而是走了eureka默認的服務地址http://localhost:8761/eureka/,然后默認的的確沒有這個服務,就導致報錯

2021-09-29 15:55:15.705  INFO 12672 --- [           main] c.n.d.s.t.d.RedirectingEurekaHttpClient  : Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://localhost:8761/eureka/}, exception=I/O error on GET request for "http://localhost:8761/eureka/apps/": Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect stacktrace=org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8761/eureka/apps/": Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
 
 
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to localhost:8761 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect

但是為什么沒有獲取到配置里面的地址,而走了默認的服務地址呢?接下來我們來看看是何原因呢?

二、版本說明

首先說明下此次出現問題的軟體版本說明

Spring Boot: v2.5.5

Spring Cloud: 2020.0.4

jdk:1.8

pom.xml檔案如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.joshua317</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2020.0.4</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
 
</project>

三、解決

為了避免問題分析程序繁瑣,先說解決方案,把問題解決后再去看原理

方案一:

把配置里面的default-zone換成defaultZone

server:
  port: 8081
  error:
    path: ./logs/error
eureka:
  client:
    service-url:
      defaultZone: http://eureka.joshua317.com/eureka/

方案二:

指定eureka.client.region,eureka.client.availability-zones等屬性值

server:
  port: 8081
  error:
    path: ./logs/error
eureka:
  client:
    region: default
    availability-zones:
      default: default-zone
    service-url:
      default-zone: http://eureka.joshua317.com/eureka/

其中,eureka.client.region屬性可理解為是地理上的磁區,比如北京,上海這種,或者可以自定義,一個服務只能屬于一個Region;

eureka.client.availability-zones屬性就是可用的Zone的集合,Zone表示一個區域,常用于實作不同網路磁區的實體配置,已實作負載均衡的區域親和性,一個Region可以包含多個Zone

eureka.client.service-url屬性就是服務的url,eureka的服務地址

比如我們可以如下配置,設定多個zone,每個zone對應一個eureka服務地址

server:
  port: 8081
  error:
    path: ./logs/error
eureka:
  client:
    region: beijing
    availability-zones:
      beijing: beijing-zone1,beijing-zone2,beijing-zone3
    service-url:
      beijing-zone1: http://eureka-server1:8761/eureka/
      beijing-zone2: http://eureka-server2:8762/eureka/
      beijing-zone2: http://eureka-server3:8763/eureka/

具體使用哪個方案,可根據我們專案的實際情況進行選擇

拓展:

eureka.instance.lease-renewal-interval-in-seconds控制心跳周期間隔時間,如:eureka.instance.lease-renewal-interval-in-seconds=30;

eureka.instance.lease-expiration-duration-in-seconds控制服務時效的時間,指定距離最后一次心跳時間多少秒后未續約,則讓注冊中心剔除實體(需要同時關閉保護模式才能使過期節點被剔除),如:

eureka.instance.lease-expiration-duration-in-seconds=120

四、問題分析

我們第一部分問題的時候提到配置沒有獲取到,沒有生效,既然問題源于組態檔沒有生效,那么Spring Boot是如何加載配置的呢eureka.clinet的組態檔呢?現在我們來分析下eureka客戶端獲取配置的原理,

我們通過ctrl+shift+N搜索下eureka相關的檔案,找到EurekaClientConfig,可以看到是一個interface介面檔案,看下這個檔案的內容

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
 
package com.netflix.discovery;
 
import com.google.inject.ImplementedBy;
import com.netflix.discovery.shared.transport.EurekaTransportConfig;
import java.util.List;
import javax.annotation.Nullable;
 
@ImplementedBy(DefaultEurekaClientConfig.class)
public interface EurekaClientConfig {
    int getRegistryFetchIntervalSeconds();
 
    int getInstanceInfoReplicationIntervalSeconds();
 
    int getInitialInstanceInfoReplicationIntervalSeconds();
 
    int getEurekaServiceUrlPollIntervalSeconds();
 
    String getProxyHost();
 
    String getProxyPort();
 
    String getProxyUserName();
 
    String getProxyPassword();
 
    /** @deprecated */
    boolean shouldGZipContent();
 
    int getEurekaServerReadTimeoutSeconds();
 
    int getEurekaServerConnectTimeoutSeconds();
 
    String getBackupRegistryImpl();
 
    int getEurekaServerTotalConnections();
 
    int getEurekaServerTotalConnectionsPerHost();
 
    String getEurekaServerURLContext();
 
    String getEurekaServerPort();
 
    String getEurekaServerDNSName();
 
    boolean shouldUseDnsForFetchingServiceUrls();
 
    boolean shouldRegisterWithEureka();
 
    default boolean shouldUnregisterOnShutdown() {
        return true;
    }
 
    boolean shouldPreferSameZoneEureka();
 
    boolean allowRedirects();
 
    boolean shouldLogDeltaDiff();
 
    boolean shouldDisableDelta();
 
    @Nullable
    String fetchRegistryForRemoteRegions();
 
    String getRegion();
 
    String[] getAvailabilityZones(String var1);
 
    List<String> getEurekaServerServiceUrls(String var1);
 
    boolean shouldFilterOnlyUpInstances();
 
    int getEurekaConnectionIdleTimeoutSeconds();
 
    boolean shouldFetchRegistry();
 
    default boolean shouldEnforceFetchRegistryAtInit() {
        return false;
    }
 
    @Nullable
    String getRegistryRefreshSingleVipAddress();
 
    int getHeartbeatExecutorThreadPoolSize();
 
    int getHeartbeatExecutorExponentialBackOffBound();
 
    int getCacheRefreshExecutorThreadPoolSize();
 
    int getCacheRefreshExecutorExponentialBackOffBound();
 
    String getDollarReplacement();
 
    String getEscapeCharReplacement();
 
    boolean shouldOnDemandUpdateStatusChange();
 
    default boolean shouldEnforceRegistrationAtInit() {
        return false;
    }
 
    String getEncoderName();
 
    String getDecoderName();
 
    String getClientDataAccept();
 
    String getExperimental(String var1);
 
    EurekaTransportConfig getTransportConfig();
}

通過查看,發現有一個List物件的方法:getEurekaServerServiceUrls

image

我們看下是哪個類實作了這個介面,經查找EurekaClientConfigBean類實作了該介面的方法

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
 
package org.springframework.cloud.netflix.eureka;
 
import com.netflix.appinfo.EurekaAccept;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.shared.transport.EurekaTransportConfig;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.core.Ordered;
import org.springframework.core.env.PropertyResolver;
import org.springframework.util.StringUtils;
 
@ConfigurationProperties("eureka.client")
public class EurekaClientConfigBean implements EurekaClientConfig, Ordered {
    public static final String PREFIX = "eureka.client";
    public static final String DEFAULT_URL = "http://localhost:8761/eureka/";
    public static final String DEFAULT_ZONE = "defaultZone";
    private static final int MINUTES = 60;
    @Autowired(
        required = false
    )
    PropertyResolver propertyResolver;
    private boolean enabled = true;
    @NestedConfigurationProperty
    private EurekaTransportConfig transport = new CloudEurekaTransportConfig();
    private int registryFetchIntervalSeconds = 30;
    private int instanceInfoReplicationIntervalSeconds = 30;
    private int initialInstanceInfoReplicationIntervalSeconds = 40;
    private int eurekaServiceUrlPollIntervalSeconds = 300;
    private String proxyPort;
    private String proxyHost;
    private String proxyUserName;
    private String proxyPassword;
    private int eurekaServerReadTimeoutSeconds = 8;
    private int eurekaServerConnectTimeoutSeconds = 5;
    private String backupRegistryImpl;
    private int eurekaServerTotalConnections = 200;
    private int eurekaServerTotalConnectionsPerHost = 50;
    private String eurekaServerURLContext;
    private String eurekaServerPort;
    private String eurekaServerDNSName;
    private String region = "us-east-1";
    private int eurekaConnectionIdleTimeoutSeconds = 30;
    private String registryRefreshSingleVipAddress;
    private int heartbeatExecutorThreadPoolSize = 2;
    private int heartbeatExecutorExponentialBackOffBound = 10;
    private int cacheRefreshExecutorThreadPoolSize = 2;
    private int cacheRefreshExecutorExponentialBackOffBound = 10;
    private Map<String, String> serviceUrl = new HashMap();
    private boolean gZipContent;
    private boolean useDnsForFetchingServiceUrls;
    private boolean registerWithEureka;
    private boolean preferSameZoneEureka;
    private boolean logDeltaDiff;
    private boolean disableDelta;
    private String fetchRemoteRegionsRegistry;
    private Map<String, String> availabilityZones;
    private boolean filterOnlyUpInstances;
    private boolean fetchRegistry;
    private String dollarReplacement;
    private String escapeCharReplacement;
    private boolean allowRedirects;
    private boolean onDemandUpdateStatusChange;
    private String encoderName;
    private String decoderName;
    private String clientDataAccept;
    private boolean shouldUnregisterOnShutdown;
    private boolean shouldEnforceRegistrationAtInit;
    private int order;
 
    public EurekaClientConfigBean() {
        this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");
        this.gZipContent = true;
        this.useDnsForFetchingServiceUrls = false;
        this.registerWithEureka = true;
        this.preferSameZoneEureka = true;
        this.availabilityZones = new HashMap();
        this.filterOnlyUpInstances = true;
        this.fetchRegistry = true;
        this.dollarReplacement = "_-";
        this.escapeCharReplacement = "__";
        this.allowRedirects = false;
        this.onDemandUpdateStatusChange = true;
        this.clientDataAccept = EurekaAccept.full.name();
        this.shouldUnregisterOnShutdown = true;
        this.shouldEnforceRegistrationAtInit = false;
        this.order = 0;
    }
 
    public boolean shouldGZipContent() {
        return this.gZipContent;
    }
 
    public boolean shouldUseDnsForFetchingServiceUrls() {
        return this.useDnsForFetchingServiceUrls;
    }
 
    public boolean shouldRegisterWithEureka() {
        return this.registerWithEureka;
    }
 
    public boolean shouldPreferSameZoneEureka() {
        return this.preferSameZoneEureka;
    }
 
    public boolean shouldLogDeltaDiff() {
        return this.logDeltaDiff;
    }
 
    public boolean shouldDisableDelta() {
        return this.disableDelta;
    }
 
    public boolean shouldUnregisterOnShutdown() {
        return this.shouldUnregisterOnShutdown;
    }
 
    public boolean shouldEnforceRegistrationAtInit() {
        return this.shouldEnforceRegistrationAtInit;
    }
 
    public String fetchRegistryForRemoteRegions() {
        return this.fetchRemoteRegionsRegistry;
    }
 
    public String[] getAvailabilityZones(String region) {
        String value = https://www.cnblogs.com/xsure/p/(String)this.availabilityZones.get(region);
        if (value == null) {
            value ="defaultZone";
        }
 
        return value.split(",");
    }
 
    public List<String> getEurekaServerServiceUrls(String myZone) {
        String serviceUrls = (String)this.serviceUrl.get(myZone);
        if (serviceUrls == null || serviceUrls.isEmpty()) {
            serviceUrls = (String)this.serviceUrl.get("defaultZone");
        }
 
        if (!StringUtils.isEmpty(serviceUrls)) {
            String[] serviceUrlsSplit = StringUtils.commaDelimitedListToStringArray(serviceUrls);
            List<String> eurekaServiceUrls = new ArrayList(serviceUrlsSplit.length);
            String[] var5 = serviceUrlsSplit;
            int var6 = serviceUrlsSplit.length;
 
            for(int var7 = 0; var7 < var6; ++var7) {
                String eurekaServiceUrl = var5[var7];
                if (!this.endsWithSlash(eurekaServiceUrl)) {
                    eurekaServiceUrl = eurekaServiceUrl + "/";
                }
 
                eurekaServiceUrls.add(eurekaServiceUrl.trim());
            }
 
            return eurekaServiceUrls;
        } else {
            return new ArrayList();
        }
    }
 
    private boolean endsWithSlash(String url) {
        return url.endsWith("/");
    }
 
    public boolean shouldFilterOnlyUpInstances() {
        return this.filterOnlyUpInstances;
    }
 
    public boolean shouldFetchRegistry() {
        return this.fetchRegistry;
    }
 
    public boolean allowRedirects() {
        return this.allowRedirects;
    }
 
    public boolean shouldOnDemandUpdateStatusChange() {
        return this.onDemandUpdateStatusChange;
    }
 
    public String getExperimental(String name) {
        return this.propertyResolver != null ? (String)this.propertyResolver.getProperty("eureka.client.experimental." + name, String.class, (Object)null) : null;
    }
 
    public EurekaTransportConfig getTransportConfig() {
        return this.getTransport();
    }
 
    public PropertyResolver getPropertyResolver() {
        return this.propertyResolver;
    }
 
    public void setPropertyResolver(PropertyResolver propertyResolver) {
        this.propertyResolver = propertyResolver;
    }
 
    public boolean isEnabled() {
        return this.enabled;
    }
 
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
 
    public EurekaTransportConfig getTransport() {
        return this.transport;
    }
 
    public void setTransport(EurekaTransportConfig transport) {
        this.transport = transport;
    }
 
    public int getRegistryFetchIntervalSeconds() {
        return this.registryFetchIntervalSeconds;
    }
 
    public void setRegistryFetchIntervalSeconds(int registryFetchIntervalSeconds) {
        this.registryFetchIntervalSeconds = registryFetchIntervalSeconds;
    }
 
    public int getInstanceInfoReplicationIntervalSeconds() {
        return this.instanceInfoReplicationIntervalSeconds;
    }
 
    public void setInstanceInfoReplicationIntervalSeconds(int instanceInfoReplicationIntervalSeconds) {
        this.instanceInfoReplicationIntervalSeconds = instanceInfoReplicationIntervalSeconds;
    }
 
    public int getInitialInstanceInfoReplicationIntervalSeconds() {
        return this.initialInstanceInfoReplicationIntervalSeconds;
    }
 
    public void setInitialInstanceInfoReplicationIntervalSeconds(int initialInstanceInfoReplicationIntervalSeconds) {
        this.initialInstanceInfoReplicationIntervalSeconds = initialInstanceInfoReplicationIntervalSeconds;
    }
 
    public int getEurekaServiceUrlPollIntervalSeconds() {
        return this.eurekaServiceUrlPollIntervalSeconds;
    }
 
    public void setEurekaServiceUrlPollIntervalSeconds(int eurekaServiceUrlPollIntervalSeconds) {
        this.eurekaServiceUrlPollIntervalSeconds = eurekaServiceUrlPollIntervalSeconds;
    }
 
    public String getProxyPort() {
        return this.proxyPort;
    }
 
    public void setProxyPort(String proxyPort) {
        this.proxyPort = proxyPort;
    }
 
    public String getProxyHost() {
        return this.proxyHost;
    }
 
    public void setProxyHost(String proxyHost) {
        this.proxyHost = proxyHost;
    }
 
    public String getProxyUserName() {
        return this.proxyUserName;
    }
 
    public void setProxyUserName(String proxyUserName) {
        this.proxyUserName = proxyUserName;
    }
 
    public String getProxyPassword() {
        return this.proxyPassword;
    }
 
    public void setProxyPassword(String proxyPassword) {
        this.proxyPassword = proxyPassword;
    }
 
    public int getEurekaServerReadTimeoutSeconds() {
        return this.eurekaServerReadTimeoutSeconds;
    }
 
    public void setEurekaServerReadTimeoutSeconds(int eurekaServerReadTimeoutSeconds) {
        this.eurekaServerReadTimeoutSeconds = eurekaServerReadTimeoutSeconds;
    }
 
    public int getEurekaServerConnectTimeoutSeconds() {
        return this.eurekaServerConnectTimeoutSeconds;
    }
 
    public void setEurekaServerConnectTimeoutSeconds(int eurekaServerConnectTimeoutSeconds) {
        this.eurekaServerConnectTimeoutSeconds = eurekaServerConnectTimeoutSeconds;
    }
 
    public String getBackupRegistryImpl() {
        return this.backupRegistryImpl;
    }
 
    public void setBackupRegistryImpl(String backupRegistryImpl) {
        this.backupRegistryImpl = backupRegistryImpl;
    }
 
    public int getEurekaServerTotalConnections() {
        return this.eurekaServerTotalConnections;
    }
 
    public void setEurekaServerTotalConnections(int eurekaServerTotalConnections) {
        this.eurekaServerTotalConnections = eurekaServerTotalConnections;
    }
 
    public int getEurekaServerTotalConnectionsPerHost() {
        return this.eurekaServerTotalConnectionsPerHost;
    }
 
    public void setEurekaServerTotalConnectionsPerHost(int eurekaServerTotalConnectionsPerHost) {
        this.eurekaServerTotalConnectionsPerHost = eurekaServerTotalConnectionsPerHost;
    }
 
    public String getEurekaServerURLContext() {
        return this.eurekaServerURLContext;
    }
 
    public void setEurekaServerURLContext(String eurekaServerURLContext) {
        this.eurekaServerURLContext = eurekaServerURLContext;
    }
 
    public String getEurekaServerPort() {
        return this.eurekaServerPort;
    }
 
    public void setEurekaServerPort(String eurekaServerPort) {
        this.eurekaServerPort = eurekaServerPort;
    }
 
    public String getEurekaServerDNSName() {
        return this.eurekaServerDNSName;
    }
 
    public void setEurekaServerDNSName(String eurekaServerDNSName) {
        this.eurekaServerDNSName = eurekaServerDNSName;
    }
 
    public String getRegion() {
        return this.region;
    }
 
    public void setRegion(String region) {
        this.region = region;
    }
 
    public int getEurekaConnectionIdleTimeoutSeconds() {
        return this.eurekaConnectionIdleTimeoutSeconds;
    }
 
    public void setEurekaConnectionIdleTimeoutSeconds(int eurekaConnectionIdleTimeoutSeconds) {
        this.eurekaConnectionIdleTimeoutSeconds = eurekaConnectionIdleTimeoutSeconds;
    }
 
    public String getRegistryRefreshSingleVipAddress() {
        return this.registryRefreshSingleVipAddress;
    }
 
    public void setRegistryRefreshSingleVipAddress(String registryRefreshSingleVipAddress) {
        this.registryRefreshSingleVipAddress = registryRefreshSingleVipAddress;
    }
 
    public int getHeartbeatExecutorThreadPoolSize() {
        return this.heartbeatExecutorThreadPoolSize;
    }
 
    public void setHeartbeatExecutorThreadPoolSize(int heartbeatExecutorThreadPoolSize) {
        this.heartbeatExecutorThreadPoolSize = heartbeatExecutorThreadPoolSize;
    }
 
    public int getHeartbeatExecutorExponentialBackOffBound() {
        return this.heartbeatExecutorExponentialBackOffBound;
    }
 
    public void setHeartbeatExecutorExponentialBackOffBound(int heartbeatExecutorExponentialBackOffBound) {
        this.heartbeatExecutorExponentialBackOffBound = heartbeatExecutorExponentialBackOffBound;
    }
 
    public int getCacheRefreshExecutorThreadPoolSize() {
        return this.cacheRefreshExecutorThreadPoolSize;
    }
 
    public void setCacheRefreshExecutorThreadPoolSize(int cacheRefreshExecutorThreadPoolSize) {
        this.cacheRefreshExecutorThreadPoolSize = cacheRefreshExecutorThreadPoolSize;
    }
 
    public int getCacheRefreshExecutorExponentialBackOffBound() {
        return this.cacheRefreshExecutorExponentialBackOffBound;
    }
 
    public void setCacheRefreshExecutorExponentialBackOffBound(int cacheRefreshExecutorExponentialBackOffBound) {
        this.cacheRefreshExecutorExponentialBackOffBound = cacheRefreshExecutorExponentialBackOffBound;
    }
 
    public Map<String, String> getServiceUrl() {
        return this.serviceUrl;
    }
 
    public void setServiceUrl(Map<String, String> serviceUrl) {
        this.serviceUrl = serviceUrl;
    }
 
    public boolean isgZipContent() {
        return this.gZipContent;
    }
 
    public void setgZipContent(boolean gZipContent) {
        this.gZipContent = gZipContent;
    }
 
    public boolean isUseDnsForFetchingServiceUrls() {
        return this.useDnsForFetchingServiceUrls;
    }
 
    public void setUseDnsForFetchingServiceUrls(boolean useDnsForFetchingServiceUrls) {
        this.useDnsForFetchingServiceUrls = useDnsForFetchingServiceUrls;
    }
 
    public boolean isRegisterWithEureka() {
        return this.registerWithEureka;
    }
 
    public void setRegisterWithEureka(boolean registerWithEureka) {
        this.registerWithEureka = registerWithEureka;
    }
 
    public boolean isPreferSameZoneEureka() {
        return this.preferSameZoneEureka;
    }
 
    public void setPreferSameZoneEureka(boolean preferSameZoneEureka) {
        this.preferSameZoneEureka = preferSameZoneEureka;
    }
 
    public boolean isLogDeltaDiff() {
        return this.logDeltaDiff;
    }
 
    public void setLogDeltaDiff(boolean logDeltaDiff) {
        this.logDeltaDiff = logDeltaDiff;
    }
 
    public boolean isDisableDelta() {
        return this.disableDelta;
    }
 
    public void setDisableDelta(boolean disableDelta) {
        this.disableDelta = disableDelta;
    }
 
    public String getFetchRemoteRegionsRegistry() {
        return this.fetchRemoteRegionsRegistry;
    }
 
    public void setFetchRemoteRegionsRegistry(String fetchRemoteRegionsRegistry) {
        this.fetchRemoteRegionsRegistry = fetchRemoteRegionsRegistry;
    }
 
    public Map<String, String> getAvailabilityZones() {
        return this.availabilityZones;
    }
 
    public void setAvailabilityZones(Map<String, String> availabilityZones) {
        this.availabilityZones = availabilityZones;
    }
 
    public boolean isFilterOnlyUpInstances() {
        return this.filterOnlyUpInstances;
    }
 
    public void setFilterOnlyUpInstances(boolean filterOnlyUpInstances) {
        this.filterOnlyUpInstances = filterOnlyUpInstances;
    }
 
    public boolean isFetchRegistry() {
        return this.fetchRegistry;
    }
 
    public void setFetchRegistry(boolean fetchRegistry) {
        this.fetchRegistry = fetchRegistry;
    }
 
    public String getDollarReplacement() {
        return this.dollarReplacement;
    }
 
    public void setDollarReplacement(String dollarReplacement) {
        this.dollarReplacement = dollarReplacement;
    }
 
    public String getEscapeCharReplacement() {
        return this.escapeCharReplacement;
    }
 
    public void setEscapeCharReplacement(String escapeCharReplacement) {
        this.escapeCharReplacement = escapeCharReplacement;
    }
 
    public boolean isAllowRedirects() {
        return this.allowRedirects;
    }
 
    public void setAllowRedirects(boolean allowRedirects) {
        this.allowRedirects = allowRedirects;
    }
 
    public boolean isOnDemandUpdateStatusChange() {
        return this.onDemandUpdateStatusChange;
    }
 
    public void setOnDemandUpdateStatusChange(boolean onDemandUpdateStatusChange) {
        this.onDemandUpdateStatusChange = onDemandUpdateStatusChange;
    }
 
    public String getEncoderName() {
        return this.encoderName;
    }
 
    public void setEncoderName(String encoderName) {
        this.encoderName = encoderName;
    }
 
    public String getDecoderName() {
        return this.decoderName;
    }
 
    public void setDecoderName(String decoderName) {
        this.decoderName = decoderName;
    }
 
    public String getClientDataAccept() {
        return this.clientDataAccept;
    }
 
    public void setClientDataAccept(String clientDataAccept) {
        this.clientDataAccept = clientDataAccept;
    }
 
    public boolean isShouldUnregisterOnShutdown() {
        return this.shouldUnregisterOnShutdown;
    }
 
    public void setShouldUnregisterOnShutdown(boolean shouldUnregisterOnShutdown) {
        this.shouldUnregisterOnShutdown = shouldUnregisterOnShutdown;
    }
 
    public boolean isShouldEnforceRegistrationAtInit() {
        return this.shouldEnforceRegistrationAtInit;
    }
 
    public void setShouldEnforceRegistrationAtInit(boolean shouldEnforceRegistrationAtInit) {
        this.shouldEnforceRegistrationAtInit = shouldEnforceRegistrationAtInit;
    }
 
    public int getOrder() {
        return this.order;
    }
 
    public void setOrder(int order) {
        this.order = order;
    }
 
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        } else if (o != null && this.getClass() == o.getClass()) {
            EurekaClientConfigBean that = (EurekaClientConfigBean)o;
            return Objects.equals(this.propertyResolver, that.propertyResolver) && this.enabled == that.enabled && Objects.equals(this.transport, that.transport) && this.registryFetchIntervalSeconds == that.registryFetchIntervalSeconds && this.instanceInfoReplicationIntervalSeconds == that.instanceInfoReplicationIntervalSeconds && this.initialInstanceInfoReplicationIntervalSeconds == that.initialInstanceInfoReplicationIntervalSeconds && this.eurekaServiceUrlPollIntervalSeconds == that.eurekaServiceUrlPollIntervalSeconds && this.eurekaServerReadTimeoutSeconds == that.eurekaServerReadTimeoutSeconds && this.eurekaServerConnectTimeoutSeconds == that.eurekaServerConnectTimeoutSeconds && this.eurekaServerTotalConnections == that.eurekaServerTotalConnections && this.eurekaServerTotalConnectionsPerHost == that.eurekaServerTotalConnectionsPerHost && this.eurekaConnectionIdleTimeoutSeconds == that.eurekaConnectionIdleTimeoutSeconds && this.heartbeatExecutorThreadPoolSize == that.heartbeatExecutorThreadPoolSize && this.heartbeatExecutorExponentialBackOffBound == that.heartbeatExecutorExponentialBackOffBound && this.cacheRefreshExecutorThreadPoolSize == that.cacheRefreshExecutorThreadPoolSize && this.cacheRefreshExecutorExponentialBackOffBound == that.cacheRefreshExecutorExponentialBackOffBound && this.gZipContent == that.gZipContent && this.useDnsForFetchingServiceUrls == that.useDnsForFetchingServiceUrls && this.registerWithEureka == that.registerWithEureka && this.preferSameZoneEureka == that.preferSameZoneEureka && this.logDeltaDiff == that.logDeltaDiff && this.disableDelta == that.disableDelta && this.filterOnlyUpInstances == that.filterOnlyUpInstances && this.fetchRegistry == that.fetchRegistry && this.allowRedirects == that.allowRedirects && this.onDemandUpdateStatusChange == that.onDemandUpdateStatusChange && this.shouldUnregisterOnShutdown == that.shouldUnregisterOnShutdown && this.shouldEnforceRegistrationAtInit == that.shouldEnforceRegistrationAtInit && Objects.equals(this.proxyPort, that.proxyPort) && Objects.equals(this.proxyHost, that.proxyHost) && Objects.equals(this.proxyUserName, that.proxyUserName) && Objects.equals(this.proxyPassword, that.proxyPassword) && Objects.equals(this.backupRegistryImpl, that.backupRegistryImpl) && Objects.equals(this.eurekaServerURLContext, that.eurekaServerURLContext) && Objects.equals(this.eurekaServerPort, that.eurekaServerPort) && Objects.equals(this.eurekaServerDNSName, that.eurekaServerDNSName) && Objects.equals(this.region, that.region) && Objects.equals(this.registryRefreshSingleVipAddress, that.registryRefreshSingleVipAddress) && Objects.equals(this.serviceUrl, that.serviceUrl) && Objects.equals(this.fetchRemoteRegionsRegistry, that.fetchRemoteRegionsRegistry) && Objects.equals(this.availabilityZones, that.availabilityZones) && Objects.equals(this.dollarReplacement, that.dollarReplacement) && Objects.equals(this.escapeCharReplacement, that.escapeCharReplacement) && Objects.equals(this.encoderName, that.encoderName) && Objects.equals(this.decoderName, that.decoderName) && Objects.equals(this.clientDataAccept, that.clientDataAccept) && Objects.equals(this.order, that.order);
        } else {
            return false;
        }
    }
 
    public int hashCode() {
        return Objects.hash(new Object[]{this.propertyResolver, this.enabled, this.transport, this.registryFetchIntervalSeconds, this.instanceInfoReplicationIntervalSeconds, this.initialInstanceInfoReplicationIntervalSeconds, this.eurekaServiceUrlPollIntervalSeconds, this.proxyPort, this.proxyHost, this.proxyUserName, this.proxyPassword, this.eurekaServerReadTimeoutSeconds, this.eurekaServerConnectTimeoutSeconds, this.backupRegistryImpl, this.eurekaServerTotalConnections, this.eurekaServerTotalConnectionsPerHost, this.eurekaServerURLContext, this.eurekaServerPort, this.eurekaServerDNSName, this.region, this.eurekaConnectionIdleTimeoutSeconds, this.registryRefreshSingleVipAddress, this.heartbeatExecutorThreadPoolSize, this.heartbeatExecutorExponentialBackOffBound, this.cacheRefreshExecutorThreadPoolSize, this.cacheRefreshExecutorExponentialBackOffBound, this.serviceUrl, this.gZipContent, this.useDnsForFetchingServiceUrls, this.registerWithEureka, this.preferSameZoneEureka, this.logDeltaDiff, this.disableDelta, this.fetchRemoteRegionsRegistry, this.availabilityZones, this.filterOnlyUpInstances, this.fetchRegistry, this.dollarReplacement, this.escapeCharReplacement, this.allowRedirects, this.onDemandUpdateStatusChange, this.encoderName, this.decoderName, this.clientDataAccept, this.shouldUnregisterOnShutdown, this.shouldEnforceRegistrationAtInit, this.order});
    }
 
    public String toString() {
        return "EurekaClientConfigBean{" + "propertyResolver=" + this.propertyResolver + ", " + "enabled=" + this.enabled + ", " + "transport=" + this.transport + ", " + "registryFetchIntervalSeconds=" + this.registryFetchIntervalSeconds + ", " + "instanceInfoReplicationIntervalSeconds=" + this.instanceInfoReplicationIntervalSeconds + ", " + "initialInstanceInfoReplicationIntervalSeconds=" + this.initialInstanceInfoReplicationIntervalSeconds + ", " + "eurekaServiceUrlPollIntervalSeconds=" + this.eurekaServiceUrlPollIntervalSeconds + ", " + "proxyPort='" + this.proxyPort + "', " + "proxyHost='" + this.proxyHost + "', " + "proxyUserName='" + this.proxyUserName + "', " + "proxyPassword='" + this.proxyPassword + "', " + "eurekaServerReadTimeoutSeconds=" + this.eurekaServerReadTimeoutSeconds + ", " + "eurekaServerConnectTimeoutSeconds=" + this.eurekaServerConnectTimeoutSeconds + ", " + "backupRegistryImpl='" + this.backupRegistryImpl + "', " + "eurekaServerTotalConnections=" + this.eurekaServerTotalConnections + ", " + "eurekaServerTotalConnectionsPerHost=" + this.eurekaServerTotalConnectionsPerHost + ", " + "eurekaServerURLContext='" + this.eurekaServerURLContext + "', " + "eurekaServerPort='" + this.eurekaServerPort + "', " + "eurekaServerDNSName='" + this.eurekaServerDNSName + "', " + "region='" + this.region + "', " + "eurekaConnectionIdleTimeoutSeconds=" + this.eurekaConnectionIdleTimeoutSeconds + ", " + "registryRefreshSingleVipAddress='" + this.registryRefreshSingleVipAddress + "', " + "heartbeatExecutorThreadPoolSize=" + this.heartbeatExecutorThreadPoolSize + ", " + "heartbeatExecutorExponentialBackOffBound=" + this.heartbeatExecutorExponentialBackOffBound + ", " + "cacheRefreshExecutorThreadPoolSize=" + this.cacheRefreshExecutorThreadPoolSize + ", " + "cacheRefreshExecutorExponentialBackOffBound=" + this.cacheRefreshExecutorExponentialBackOffBound + ", " + "serviceUrl=" + this.serviceUrl + ", " + "gZipContent=" + this.gZipContent + ", " + "useDnsForFetchingServiceUrls=" + this.useDnsForFetchingServiceUrls + ", " + "registerWithEureka=" + this.registerWithEureka + ", " + "preferSameZoneEureka=" + this.preferSameZoneEureka + ", " + "logDeltaDiff=" + this.logDeltaDiff + ", " + "disableDelta=" + this.disableDelta + ", " + "fetchRemoteRegionsRegistry='" + this.fetchRemoteRegionsRegistry + "', " + "availabilityZones=" + this.availabilityZones + ", " + "filterOnlyUpInstances=" + this.filterOnlyUpInstances + ", " + "fetchRegistry=" + this.fetchRegistry + ", " + "dollarReplacement='" + this.dollarReplacement + "', " + "escapeCharReplacement='" + this.escapeCharReplacement + "', " + "allowRedirects=" + this.allowRedirects + ", " + "onDemandUpdateStatusChange=" + this.onDemandUpdateStatusChange + ", " + "encoderName='" + this.encoderName + "', " + "decoderName='" + this.decoderName + "', " + "clientDataAccept='" + this.clientDataAccept + "', " + "shouldUnregisterOnShutdown='" + this.shouldUnregisterOnShutdown + "shouldEnforceRegistrationAtInit='" + this.shouldEnforceRegistrationAtInit + "', " + "order='" + this.order + "'}";
    }
}

接下來,我們斷點看一下,發現myZone的值為defaultZone而不是default-zone,有兩個serviceUrl,分別是default-zone和defaultZone
image

default-zone -> http://eureka.joshua317.com/eureka/

defaultZone -> http://localhost:8761/eureka/

在沒有制定region的情況下,會使用defaultZone從ServiceUrl中查詢Eureka Server的URL串列,所以使用代碼默認初始化的地址http://localhost:8761/eureka/,所以出現了上面的錯誤,
image

具體為什么呢,我們接著往下走,進入到了EndpointUtils類中的getServiceUrlsMapFromConfig,我們可以看到region為us-east-1默認值

instanceZone="defaultZone"
region="us-east-1"
zone="defaultZone"
availZones[myZoneOffset]="defaultZone"

因為沒有在yml配置region屬性,所以才使用了默認us-east-1,并且availabilityZones為空,所以myZone使用的是默認是值defaultZone,詳情見getZone()方法,

image

image

然后我們繼續追代碼,找到了類ConfigClusterResolver的getClusterEndpointsFromConfig方法,在這里面我們可以看到myZone的獲取
image

那有人可能會問為什么service-url就可以呢,我們在EurekaClientConfigBean類中setServiceUrl方法處斷點看下

image

在EurekaClientConfigBean呼叫sercviceUrl之前,先經過 BeanProperty.setValue()處理了, 并且beanProperty物件的setter方法正好sercviceUrl,而BeanProperty的屬性name是service-url這和我們的組態檔是一樣的,
image

五、總結

在我們組態檔寫入配置的程序中,屬性里面的一些鍵名是駝峰,還是中劃線,主要看我們底層代碼實作是如何處理的,我們可以通過斷點追代碼進行排查分析,

轉載自joshua317博客 Spring Boot-yaml格式,eureka客戶端配置default-zone報錯問題 - joshua317的博客
————————————————
著作權宣告:本文為CSDN博主「joshua317」的原創文章,遵循CC 4.0 BY-SA著作權協議,轉載請附上原文出處鏈接及本宣告,
原文鏈接:https://blog.csdn.net/joshua317/article/details/120556413

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/491352.html

標籤:Java

上一篇:面試官:高并發場景下,你們是怎么保證資料的一致性的?

下一篇:如何從UITableView擴展中根據表格視圖的版本狀態顯示完成按鈕?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more