In spring boot yaml format, the eureka client configures the default zone and reports an error

This article is an original article of Joshua 317. Please note: reprinted from Joshua 317 blog In spring boot yaml format, the eureka client configures the default zone and reports errors - Joshua 317's blog

1, Question

When configuring eureka client, set the simple configuration of eureka client as follows:

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

After the result runs, the following error is reported:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: 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

After reading the error message below, the main reason is that the Eureka service eureka.service-url in the configuration is not obtained, but the default Eureka service address is used http://localhost:8761/eureka/ If the default service does not exist, an error will be reported

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

But why not get the address in the configuration and go to the default service address? Next, let's see why?

2, Version Description

First, explain the software version of the problem

Spring Boot: v2.5.5

Spring Cloud: 2020.0.4

jdk:1.8

pom.xml file is as follows:

<?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>

3, Settle

In order to avoid the tedious process of problem analysis, first say the solution, and then look at the principle after solving the problem

Scheme I:

Replace the default zone in the configuration with the default zone

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

Scheme II:

Specify attribute values such as eureka.client.region and 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/

The eureka.client.region attribute can be understood as a geographical partition, such as Beijing and Shanghai, or it can be customized. A service can only belong to one Region;

eureka.client.availability-zones attribute is the collection of available zones. Zone represents a Region, which is commonly used to realize the instance configuration of different network partitions, and has realized the regional affinity of load balancing. A Region can contain multiple zones

The eureka.client.service-url attribute is the URL of the service and the service address of Eureka

For example, we can configure multiple zones as follows, and each zone corresponds to a eureka service address

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/

The specific scheme can be selected according to the actual situation of our project

expand:

Eureka. Instance. Lease renewal interval in seconds controls the heartbeat cycle interval, for example: Eureka. Instance. Lease renewal interval in seconds = 30;

eureka.instance.lease-expiration-duration-in-seconds controls the service aging time. If the contract is not renewed after the last heartbeat time, let the registry eliminate the instances (you need to turn off the protection mode at the same time to eliminate the expired nodes), such as:

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

4, Problem analysis

In the first part of the question, we mentioned that the configuration was not obtained and did not take effect. Since the problem is that the configuration file did not take effect, how does Spring Boot load the configuration? The configuration file of eureka.clinet? Now let's analyze the principle of Eureka client obtaining configuration.

We can search eureka related files by ctrl+shift+N and find eureka clientconfig. We can see that it is an interface file. See the contents of this file

//
// 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();
}

Through viewing, we found that there is a method of List object: getEurekaServerServiceUrls

Let's see which class implements this interface. Find the EurekaClientConfigBean class to implement the method of this interface

//
// 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 = (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 + "'}";
    }
}

Next, we take a look at the breakpoint and find that the value of myZone is defaultZone instead of default zone. There are two serviceurls, default zone and defaultZone

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

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

If no region is specified, the default zone will be used to query the URL list of Eureka Server from the ServiceUrl, so the default initialized address of the code is used http://localhost:8761/eureka/ , so the above error occurred.

Why? We went down to getServiceUrlsMapFromConfig in the EndpointUtils class. We can see that the region is the default value of us-east-1

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

Because the region attribute is not configured in yml, the default us-east-1 is used, and the availability zones is empty. Therefore, myZone uses the default value defaultZone. See the getZone() method for details.

Then we continue to trace the code and find the getClusterEndpointsFromConfig method of the class ConfigClusterResolver, where we can see the acquisition of myZone

Some people may ask why service URL is OK. Let's look at the breakpoint at the setServiceUrl method in EurekaClientConfigBean class

Before EurekaClientConfigBean calls sercviceUrl, it is processed by BeanProperty.setValue(), and the setter method of beanproperty object happens to be sercviceUrl, and the property name of beanproperty is service URL, which is the same as our configuration file.

5, Summary

In the process of writing configuration from our configuration file, whether some key names in the attribute are humps or dashes mainly depends on how our underlying code implementation handles it. We can trace the code through breakpoints for troubleshooting and analysis.

This article is an original article of Joshua 317. Please note: reprinted from Joshua 317 blog In spring boot yaml format, the eureka client configures the default zone and reports errors - Joshua 317's blog

Keywords: Java Spring Spring Boot eureka

Added by JonathanS on Wed, 29 Sep 2021 21:55:58 +0300