博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊聊eureka client的shutdown
阅读量:6415 次
发布时间:2019-06-23

本文共 7996 字,大约阅读时间需要 26 分钟。

  hot3.png

本文主要研究一下eureka client的shutdown

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) { 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,以及EurekaAutoServiceRegistration,EurekaClient

EurekaClient

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

可以看到EurekaClient标注了@Bean(destroyMethod = "shutdown"),也就是在bean销毁的时候,会触发eurekaClient.shutdown方法

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

这里实现了Closeable接口的close方法,在spring容器关闭的时候触发,这里调用了eurekaClient.shutdown()

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

这里的start,stop实现的是Lifecycle的方法,也就在spring容器关闭的时候,会触发stop方法,然后调用的是serviceRegistry.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();			}		}	}

接收到RefreshScopeRefreshedEvent的时候,会先stop,再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
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); } } }

这里可以看到,先设置状态为DOWN,然后调用cancel方法

RestTemplateEurekaHttpClient

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

public EurekaHttpResponse
cancel(String appName, String id) { String urlPath = serviceUrl + "apps/" + appName + '/' + id; ResponseEntity
response = restTemplate.exchange(urlPath, HttpMethod.DELETE, null, Void.class); return anEurekaHttpResponse(response.getStatusCodeValue()) .headers(headersOf(response)).build(); } @Override public EurekaHttpResponse
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
response = restTemplate.exchange(urlPath, HttpMethod.POST, new HttpEntity<>(info, headers), Void.class); return anEurekaHttpResponse(response.getStatusCodeValue()) .headers(headersOf(response)).build(); }

cancel方法就是调用REST的DELETE操作,注销掉服务

小结

springcloud封装的eureka自动注册,关闭的时候主要分两大类:

  • 依赖生命周期在销毁时调用shutdown、close

EurekaRegistration是在close的时候,会触发eurekaClient.shutdown方法 EurekaAutoServiceRegistration则在stop的时候,标记状态为DOWN,发布StatusChangeEvent事件 EurekaClient则标注了@Bean(destroyMethod = "shutdown"),也就是在bean销毁的时候,会触发eurekaClient.shutdown方法

  • 期间状态变更发布StatusChangeEvent事件

com/netflix/discovery/DiscoveryClient.java有个StatusChangeListener,状态变更在需要的时候,会触发InstanceInfoReplicator的onDemandUpdate方法,该方法会调用discoveryClient.register()去与eureka server更新自身实例的状态。 这里相当于变相通过register接口更改status状态。

这里要区分一下cancel与StatusChangeEvent的区别,cancel是从eureka server删掉这条instanceInfo,而StatusChangeEvent变更状态,不会删除这条instanceInfo,只是更新status状态(status状态一共有UP,DOWN,STARTING,OUT_OF_SERVICE,UNKNOWN几类)。

doc

转载于:https://my.oschina.net/go4it/blog/1806744

你可能感兴趣的文章
如何将matlab画出的图片保存为要求精度
查看>>
淘宝实习面试经历分享
查看>>
帮Customer Architecture写的小脚本
查看>>
Calling a Batch File/EXE from an SQR
查看>>
Message Box
查看>>
坐标轴的旋转及绕某一点旋转后坐标值求解
查看>>
KVO 简单使用
查看>>
如何在Linux终端里用Shell和C输出带颜色的文字
查看>>
REST framework
查看>>
awk中begin/end的含义
查看>>
windows下流媒体nginx-rmtp-module服务器搭建及java程序调用fmpeg将rtsp转rtmp直播流【转】...
查看>>
vlc的应用之三:动态调用vlc-0.9.4的libvlc.dll【转】
查看>>
Web API核查表:设计、测试、发布API时需思考的43件事[转]
查看>>
Eclipse使用技巧
查看>>
webkit webApp 开发技术要点总结
查看>>
MVC下用户登录状态校验的问题以及解决方案--------------Action全局过滤器的使用...
查看>>
java的类加载机制
查看>>
闪电侠 Netty 小册里的骚操作
查看>>
c# dump 程序崩溃 windbg
查看>>
Docker GitHub 网站中 Readme.md 以技术者的角度翻译
查看>>