Talk about the shutdown of eureka client

sequence

This article mainly studies the shutdown of eureka client

EurekaRegistration

spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java

	@Bean
	@ConditionalOnBean(AutoServiceRegistrationProperties.class)
	@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
	public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient, CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager applicationInfoManager, ObjectProvider<HealthCheckHandler> healthCheckHandler) {
		return EurekaRegistration.builder(instanceConfig)
				.with(applicationInfoManager)
				.with(eurekaClient)
				.with(healthCheckHandler)
				.build();
	}

	@Bean
	@ConditionalOnBean(AutoServiceRegistrationProperties.class)
	@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
	public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry registry, EurekaRegistration registration) {
		return new EurekaAutoServiceRegistration(context, registry, registration);
	}

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

EurekaRegistration is automatically created here, as well as EurekaAutoServiceRegistration, EurekaClient

EurekaClient

eureka-client-1.8.8-sources.jar!/com/netflix/discovery/EurekaClient.java

You can see that EurekaClient is marked with @Bean(destroyMethod = "shutdown"), that is, when the bean is destroyed, the eurekaClient.shutdown method will be triggered

EurekaRegistration

spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaRegistration.java

public class EurekaRegistration implements Registration, Closeable {
	//......
	@Override
	public void close() throws IOException {
		this.eurekaClient.shutdown();
	}
}

The close method of the Closeable interface is implemented here, which is triggered when the spring container is closed, and eurekaClient.shutdown() is called here.

EurekaAutoServiceRegistration

spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistration.java

	@Override
	public void start() {
		// only set the port if the nonSecurePort or securePort is 0 and this.port != 0
		if (this.port.get() != 0) {
			if (this.registration.getNonSecurePort() == 0) {
				this.registration.setNonSecurePort(this.port.get());
			}

			if (this.registration.getSecurePort() == 0 && this.registration.isSecure()) {
				this.registration.setSecurePort(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);
		}
	}
	@Override
	public void stop() {
		this.serviceRegistry.deregister(this.registration);
		this.running.set(false);
	}

The start and stop here implement the Lifecycle method, that is, when the spring container is closed, the stop method will be triggered, and then serviceRegistry.deregister(this.registration) will be called.

RefreshScopeRefreshedEvent

spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java

	@Configuration
	@ConditionalOnClass(RefreshScopeRefreshedEvent.class)
	protected static class EurekaClientConfigurationRefresher {

		@Autowired(required = false)
		private EurekaClient eurekaClient;

		@Autowired(required = false)
		private EurekaAutoServiceRegistration autoRegistration;

		@EventListener(RefreshScopeRefreshedEvent.class)
		public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
			//This will force the creation of the EurkaClient bean if not already created
			//to make sure the client will be reregistered after a refresh event
			if(eurekaClient != null) {
				eurekaClient.getApplications();
			}
			if (autoRegistration != null) {
				// register in case meta data changed
				this.autoRegistration.stop();
				this.autoRegistration.start();
			}
		}
	}

When receiving RefreshScopeRefreshedEvent, it will stop first, then start

DiscoveryClient.shutdown

eureka-client-1.8.8-sources.jar!/com/netflix/discovery/DiscoveryClient.java

    public synchronized void shutdown() {
        if (isShutdown.compareAndSet(false, true)) {
            logger.info("Shutting down DiscoveryClient ...");

            if (statusChangeListener != null && applicationInfoManager != null) {
                applicationInfoManager.unregisterStatusChangeListener(statusChangeListener.getId());
            }

            cancelScheduledTasks();

            // If APPINFO was registered
            if (applicationInfoManager != null
                    && clientConfig.shouldRegisterWithEureka()
                    && clientConfig.shouldUnregisterOnShutdown()) {
                applicationInfoManager.setInstanceStatus(InstanceStatus.DOWN);
                unregister();
            }

            if (eurekaTransport != null) {
                eurekaTransport.shutdown();
            }

            heartbeatStalenessMonitor.shutdown();
            registryStalenessMonitor.shutdown();

            logger.info("Completed shut down of DiscoveryClient");
        }
    }

    /**
     * unregister w/ the eureka service.
     */
    void unregister() {
        // It can be null if shouldRegisterWithEureka == false
        if(eurekaTransport != null && eurekaTransport.registrationClient != null) {
            try {
                logger.info("Unregistering ...");
                EurekaHttpResponse<Void> httpResponse = eurekaTransport.registrationClient.cancel(instanceInfo.getAppName(), instanceInfo.getId());
                logger.info(PREFIX + "{} - deregister  status: {}", appPathIdentifier, httpResponse.getStatusCode());
            } catch (Exception e) {
                logger.error(PREFIX + "{} - de-registration failed{}", appPathIdentifier, e.getMessage(), e);
            }
        }
    }

As you can see here, first set the state to DOWN, and then call the cancel method

RestTemplateEurekaHttpClient

spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClient.java

	public EurekaHttpResponse<Void> cancel(String appName, String id) {
		String urlPath = serviceUrl + "apps/" + appName + '/' + id;

		ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.DELETE,
				null, Void.class);

		return anEurekaHttpResponse(response.getStatusCodeValue())
				.headers(headersOf(response)).build();
	}

	@Override
	public EurekaHttpResponse<Void> register(InstanceInfo info) {
		String urlPath = serviceUrl + "apps/" + info.getAppName();

		HttpHeaders headers = new HttpHeaders();
		headers.add(HttpHeaders.ACCEPT_ENCODING, "gzip");
		headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);

		ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.POST,
				new HttpEntity<>(info, headers), Void.class);

		return anEurekaHttpResponse(response.getStatusCodeValue())
				.headers(headersOf(response)).build();
	}

The cancel method is to call the DELETE operation of REST to log off the service

summary

The eureka encapsulated by springcloud is automatically registered, and it is mainly divided into two categories when it is closed:

  • Dependency life cycle calls shutdown, close when destroyed

EurekaRegistration will trigger the eurekaClient.shutdown method when EurekaRegistration is closed. EurekaAutoServiceRegistration will mark the status as DOWN when it is stopped, and publish the StatusChangeEvent event. EurekaClient is marked with @Bean(destroyMethod = "shutdown"), that is, when the bean is destroyed, Will trigger the eurekaClient.shutdown method

  • Publish StatusChangeEvent event during state change

com/netflix/discovery/DiscoveryClient.java has a StatusChangeListener. When the status changes, it will trigger the onDemandUpdate method of InstanceInfoReplicator, which will call discoveryClient.register() to update the status of its own instance with the eureka server. This is equivalent to changing the status status through the register interface in disguise.

Here to distinguish the difference between cancel and StatusChangeEvent, cancel deletes this instanceInfo from the eureka server, and StatusChangeEvent changes the state, it does not delete this instanceInfo, but only updates the status status (status status has a total of UP, DOWN, STARTING, OUT_OF_SERVICE, UNKNOWN several categories).

doc

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325253194&siteId=291194637