Eureka of Spring Cloud Source Analysis Chapter 4: How Service Registration was Initiated

Original Link: https://blog.csdn.net/boling_cavalry/article/details/82721583

In the Spring Cloud environment, both service providers and consumers will register themselves to Eureka after startup. Starting from this chapter, we will explore the code logic of the entire registration process to further understand the service registration discovery mechanism of Spring Cloud.

Overview of Chapters

Eureka's service registration discovery function involves a lot of content and is therefore divided into several articles, outlined as follows:
1. Analyse how a common SpringBoot application starts to perform service registration discovery related functions, which is the content of this article;
2. Analyse the acquisition and update logic of service lists;
3. Analyse the logic registered with Eureka;
4. Analyse the logic of renewal to Eureka;

Register the service with Eureka

If a SpringBoot application is to be registered with the Spring Cloud environment (Edgware.RELEASE version), the steps are simple:
1. Add a starter in pom.xml: spring-cloud-starter-netflix-eureka-client;
2. Add configuration: eureka.client.serviceUrl.defaultZone: http://localhost:8081/eureka/
3. Start the application;

If the registry is OK, you can find the application in the registry at this time, as shown in the red box below:

Why not use the comment @EnableDiscoveryClient

Prior to the Edgware version of Spring Cloud, the service registration discovery function would not be enabled until the annotation @EnableDiscoveryClient was added to the applied configuration class, but @EnableDiscoveryClient has become an optional option since the Edgware version. Service registration discovery can also be enabled without this annotation. <
Eureka Chapter 3 of Spring Cloud Source Analysis: Differences between EnableDiscoveryClient and EnableEurekaClient (Edgware Version)
;

Start Logical Analysis

Now analyze the application startup process to see how the registration service started:
1. spring-cloud-netflix-eureka-client-1.4.0.RELEASE.jar is an important jar package. Many configurations are in the spring.factories file inside the jar. First, determine if the jar package will appear in the applied classpath (if it is not in the classpath, these configurations will not work), and persist in the directory where pom.xml resides.Line command mvn dependency:tree, print the dependency tree, as shown below, to confirm that spring-cloud-netflix-eureka-client is indirectly dependent by the launcher spring-cloud-starter-netflix-eureka-client and therefore appears in the classpath:


2. The spring.factories file in spring-cloud-netflix-eureka-client-1.4.0.RELEASE.jar reads as follows:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.eureka.config.EurekaClientConfigServerAutoConfiguration,\
org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceAutoConfiguration,\
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\
org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,\
org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration

org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceBootstrapConfiguration
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

The above configuration information is visible, if springboot enables automatic configuration, then EurekaClientConfigServerAutoConfiguration,...Five configuration classes, EurekaDiscoveryClientConfiguration, and so on, will take effect.

3. As configured in spring.factories, the configuration in EurekaClientAutoConfiguration will take effect, including the bean s returned by this code:

@Bean
public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) {
    return new EurekaDiscoveryClient(config, client);
}
  • 1
  • 2
  • 3
  • 4


4. When the spring container initializes, all the single beans are instantiated, and the discoveryClient method of the EurekaClientAutoConfiguration is executed to get the bean instance, and an EurekaDiscoveryClient object is constructed;
5. Notice how the EurekaDiscoveryClient is constructed. The second entry is the type com.netflix.discovery.EurekaClient, which is also from the EurekaClientAutoConfiguration class, as follows:

@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
@org.springframework.cloud.context.config.annotation.RefreshScope
@Lazy
public EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config, EurekaInstanceConfig instance) {
    manager.getInfo(); // force initialization
    return new CloudEurekaClient(manager, config, this.optionalArgs,this.context);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

CloudEurekaClient's parent, com.netflix.discovery.DiscoveryClient, comes from the eureka-client package published by netflix, so it's understandable that the EurekaDiscoveryClient class is a proxy identity, true service registration discovery is delegated to netflix's open source package, and we can concentrate on using SpringCloud's offerThe service registration discovery function only needs to know EurekaDiscoveryClient, the real service is eureka-client to complete;

6. Next, you need to focus on the construction method of the com.netflix.discovery.DiscoveryClient, because it has the logic of service registration. The whole construction method is too much to look at, just the key code;

7. Among the construction methods of DiscoveryClient, the most familiar should be the log output in the following red box:

The corresponding application startup log contains this log output, as shown in the red box below:


The "us-east-1" in the red box is the default region from the configuration class EurekaClientConfigBean, which has various eureka-related configuration information, as well as the default configuration, as shown below:


8. Continue to look at the construction method of DiscoveryClient, where the initScheduledTasks method associated with service registration is called, as shown below:



9. The contents of the initScheduledTasks method are as follows, note the Chinese comment:

private void initScheduledTasks() {
    //Get service registration list information
        if (clientConfig.shouldFetchRegistry()) {
            //Cycle time for service registration list updates
            int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();
            int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();
            //Update service registration list regularly
            scheduler.schedule(
                    new TimedSupervisorTask(
                            "cacheRefresh",
                            scheduler,
                            cacheRefreshExecutor,
                            registryFetchIntervalSeconds,
                            TimeUnit.SECONDS,
                            expBackOffBound,
                            new CacheRefreshThread() //The thread executes the specific logic of the update
                    ),
                    registryFetchIntervalSeconds, TimeUnit.SECONDS);
        }

        if (clientConfig.shouldRegisterWithEureka()) {
            //Cycle time for service renewal
            int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
            int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();
            //This log is visible at application startup and reads: Starting heartbeat executor: renew interval is: 30
            logger.info("Starting heartbeat executor: " + "renew interval is: " + renewalIntervalInSecs);
            // Timed renewal
            scheduler.schedule(
                    new TimedSupervisorTask(
                            "heartbeat",
                            scheduler,
                            heartbeatExecutor,
                            renewalIntervalInSecs,
                            TimeUnit.SECONDS,
                            expBackOffBound,
                            new HeartbeatThread() //The thread executes the specific logic for renewal
                    ),
                    renewalIntervalInSecs, TimeUnit.SECONDS);

            //This Runable contains logic for service registration
            instanceInfoReplicator = new InstanceInfoReplicator(
                    this,
                    instanceInfo,
                    clientConfig.getInstanceInfoReplicationIntervalSeconds(),
                    2); // burstSize

            statusChangeListener = new ApplicationInfoManager.StatusChangeListener() {
                @Override
                public String getId() {
                    return "statusChangeListener";
                }

                @Override
                public void notify(StatusChangeEvent statusChangeEvent) {
                    if (InstanceStatus.DOWN == statusChangeEvent.getStatus() ||
                            InstanceStatus.DOWN == statusChangeEvent.getPreviousStatus()) {
                        // log at warn level if DOWN was involved
                        logger.warn("Saw local status change event {}", statusChangeEvent);
                    } else {
                        logger.info("Saw local status change event {}", statusChangeEvent);
                    }
                    instanceInfoReplicator.onDemandUpdate();
                }
            };

            if (clientConfig.shouldOnDemandUpdateStatusChange()) {
                applicationInfoManager.registerStatusChangeListener(statusChangeListener);
            }
            //Service Registration
            instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());
        } else {
            logger.info("Not registering with Eureka server per configuration");
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

There are several points to note in the above code that will continue in later chapters:
a. Periodically update the list of services;
b. Periodic service renewal;
c. The service registration logic is put into the Runnable implementation class InstanceInfoReplicator and executed in a new thread;

About Spring Cloud Project and Netflix Project

The relationship between Spring Cloud and Netflix, among other things related to registration discovery, can be aided by the following class diagram from the Great Ape DD article Spring Cloud Source Analysis (1) Eureka Salute the great god!

So far, we've learned the steps for the SpringBoot application to start the service registration function, and the next chapters will continue to dig deeper into how to update the service list.

Keywords: Spring SpringBoot xml

Added by kweathe on Sat, 07 Sep 2019 05:36:46 +0300