Spring cloud part of the source code: Eureka Client registration

1: use SpringCloud Framework procedures, in addition to Eureka Other services are Eureka Client. By default, the Eureka Register your own service instance and Eureka The server obtains registration information periodically.
Introduce in application spring-cloud-starter-eureka Dependent packages can be imported Eureka Clinet:spring-cloud-netflix-eureka-client. (It may be different versions, depending on different package names). As follows:
<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

2: In the spring cloud Netflix Eureka client package In factories, the code is as follows. Here, the automatic configuration loading class will be executed: EurekaClientAutoConfiguration. This is mainly the object required to register Eureka client.

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.bootstrap.BootstrapConfiguration=
org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceBootstrapConfiguration
org.springframework.cloud.client.discovery.EnableDiscoveryClient=
org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration

3: By default, eureka.com is configured client. The value of enabled is true. In the yml file, use Eureka For the configuration starting with client, the resolved object is EurekaClientConfigBean.
The default configuration is as follows:
registryFetchIntervalSeconds: the frequency of obtaining service instances from the erureka server. By default. Once every 30 seconds
Eurekaserverredtimeoutseconds: timeout for reading and obtaining information from eureka server. Default: 8 seconds
eurekaServerConnectTimeoutSeconds: timeout for connecting to eureka server. Default: 5 seconds
serviceUrl: the URL of eureka service registration: the default address is: http://localhost :8761/eureka. Here is a MAP. Multiple addresses can be configured
Eurekaservertotal connections: the total number of connections to eureka. Default: 200
Eurekaservertalconnectionsperhost: the number of connections to a single eureka. Default: 50
registerWithEureka: whether to register with eureka. Default value: true
fetchRegistry: whether to obtain registration information from eureka server. Default value: true

@ConfigurationProperties(EurekaClientConfigBean.PREFIX)
public class EurekaClientConfigBean implements EurekaClientConfig, EurekaConstants {
   public static final String PREFIX = "eureka.client";
 @Autowired(required = false)
   PropertyResolver propertyResolver;
 public static final String DEFAULT_URL = "http://localhost:8761" + DEFAULT_PREFIX
 + "/";
 public static final String DEFAULT_ZONE = "defaultZone";
 
 @Bean
@ConditionalOnMissingBean(value = EurekaClientConfig.class, search = SearchStrategy.CURRENT)
public EurekaClientConfigBean eurekaClientConfigBean() {
   EurekaClientConfigBean client = new EurekaClientConfigBean();
 if ("bootstrap".equals(propertyResolver.getProperty("spring.config.name"))) {
      // We don't register during bootstrap by default, but there will be another
 // chance later. client.setRegisterWithEureka(false);
 }
   return client;
}

4: To register the DiscoveryClient instance, you can obtain the service information registered on eureka from the cache through the instance object~~~~

@Bean
public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) {
   return new EurekaDiscoveryClient(config, client);
}

5: Register an instance of EurekaClient. The type is CloudEurekaClient. Its parent class is DiscoveryClient. In the constructor of this class, the scheduled tasks of registering with eureka and obtaining services from eureka will be established.

@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
public EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config) {
   return new CloudEurekaClient(manager, config, this.optionalArgs,
 this.context);
}

6: In the constructor of DiscoveryClient, in addition to the assignment of various attributes, a very important method initScheduledTasks() is called to initialize the scheduled task. Of course, if the registerWithEureka and fetchRegistry of the application are false, this method will not be executed.

private void initScheduledTasks() {
    if (clientConfig.shouldFetchRegistry()) { //If the fetchRegistry configuration is true, execute the
        // registry cache refresh timer
 int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds(); //The default is 30S, and the interval between obtaining registration information from eureka
 int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound(); //The default value is 10,
 scheduler.schedule( //Establish a task, obtain registration information from eureka, initial delay time, 30S. Task class: timedsupersortask
                new TimedSupervisorTask(
                        "cacheRefresh",
 scheduler,
 cacheRefreshExecutor,
 registryFetchIntervalSeconds,
 TimeUnit.SECONDS,
 expBackOffBound,
 new CacheRefreshThread()
                ),
 registryFetchIntervalSeconds, TimeUnit.SECONDS);
 }
    if (clientConfig.shouldRegisterWithEureka()) { //If the value of registerWithEureka configuration is true, it will be executed.
        int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
 int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound(); //Default 30 seconds
 logger.info("Starting heartbeat executor: " + "renew interval is: " + renewalIntervalInSecs);
 // Heartbeat timer
 scheduler.schedule( //Register the heartbeat timing task and send information to eureka regularly. The initial delay time is 30S
                new TimedSupervisorTask(
                        "heartbeat",
 scheduler,
 heartbeatExecutor,
 renewalIntervalInSecs,
 TimeUnit.SECONDS,
 expBackOffBound,
 new HeartbeatThread()
                ),
 renewalIntervalInSecs, TimeUnit.SECONDS);
 // InstanceInfo replicator
 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()) { //Register the event listener. According to the above code, if the status is DOWN, it will be registered to eureka immediately
            applicationInfoManager.registerStatusChangeListener(statusChangeListener);
 }
        instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds()); //Establish a scheduled task, and the initial delay time is 40S
 } else {
        logger.info("Not registering with Eureka server per configuration");
 }
}

7: In fact, in the above code, the timedsupersortask class actually executes the run methods of classes: CacheRefreshThread and HeartbeatThread. Not here. The code is not difficult.

8: In the automatic configuration, the EurekaAutoServiceRegistration object will also be instantiated. This object listens for Spring events: EmbeddedServletContainerInitializedEvent. This event will be sent when the WEB container is initialized. In this event handling method, the current node will be registered in the eureka server.

@EventListener(EmbeddedServletContainerInitializedEvent.class)
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
   // TODO: take SSL into account when Spring Boot 1.2 is available
 int localPort = event.getEmbeddedServletContainer().getPort();
 if (this.port.get() == 0) {
      log.info("Updating port to " + localPort);
 this.port.compareAndSet(0, localPort);
 start();
 }
}

public void start() {
   // only set the port if the nonSecurePort is 0 and this.port != 0
 if (this.port.get() != 0 && this.registration.getNonSecurePort() == 0) {
      this.registration.setNonSecurePort(this.port.get());
 }
   // only initialize if nonSecurePort is greater than 0 and it isn't already running
 // because of containerPortInitializer below if (!this.running.get() && this.registration.getNonSecurePort() > 0) {
      this.serviceRegistry.register(this.registration);
 this.context.publishEvent(
            new InstanceRegisteredEvent<>(this, this.registration.getInstanceConfig()));
 this.running.set(true);
 }
}

Tags: Java Spring Boot

Posted by Cronje on Wed, 04 May 2022 01:39:08 +0300