Order
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 has marked @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. 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);
}
Here, start and stop implement the Lifecycle method, which will trigger the stop method when the spring container is closed, and then call service registry. deregister (this. registration)
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 and 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 status 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 REST’s DELETE operation to cancel the service.
Summary
Eureka packaged by springcloud is automatically registered, and is mainly divided into two categories when closed:
- The dependent life cycle calls shutdown, close
The EurekaRegistration triggers the eurekaClient.shutdown method when close.
EurekaAutoServiceRegistration will mark the status as DOWN when stop and issue the StatusChangeEvent event.
EurekaClient has marked @Bean(destroyMethod = “shutdown “), that is, when the bean is destroyed, the eurekaClient.shutdown method will be triggered.
- During the state change issue StatusChangeEvent event
Com/Netflix/Discovery/DiscoverClient.java has a StatusChangeListener. When the state changes are needed, the onDemandUpdate method of InstanceInfoReplicator will be triggered. The method will call discoveryClient.register () to update the state of its own instance with eureka server.
This is equivalent to changing the status status through the register interface in a disguised form.
Here, the difference between cancel and StatesChangeEvent should be distinguished. cancel deletes this instanceInfo from eureka server, while StatesChangeEvent changes the status, does not delete this instanceInfo, but only updates the status status (the status has up, down, starting, out _ of _ service, unknown and so on).