六.SpringCloud源码剖析-Eureka Client取消注册

系列文章目录

一.SpringCloud源码剖析-Eureka核心API

二.SpringCloud源码剖析-Eureka Client 初始化过程

三.SpringCloud源码剖析-Eureka服务注册

四.SpringCloud源码剖析-Eureka服务发现

五.SpringCloud源码剖析-Eureka Client服务续约

六.SpringCloud源码剖析-Eureka Client取消注册

七.SpringCloud源码剖析-Eureka Server的自动配置

八.SpringCloud源码剖析-Eureka Server初始化流程

九.SpringCloud源码剖析-Eureka Server服务注册流程

十.SpringCloud源码剖析-Eureka Server服务续约

十一.SpringCloud源码剖析-Eureka Server服务注册表拉取

十二.SpringCloud源码剖析-Eureka Server服务剔除

十三.SpringCloud源码剖析-Eureka Server服务下线

取消注册

取消注册(服务下线)指的是EureakClient正常关闭之前,微服务会主动向EurekaServer发送下线请求,EureakServer接收到请求从注册表中剔除下线的服务

DiscoveryClient.shutdown 方法

DiscoveryClient是服务发现最核心的实现,DiscoveryClient通过shutdown 方法取消服务注册,方法上通过@PreDestroy标记该方法是实例的销毁方法,当应用关闭,容器正常关闭,Bean的销毁方法执行,源码如下:

@Singleton
public class DiscoveryClient implements EurekaClient {
....省略部分代码...
 /**
 	//关闭Eureak Client,从Eureak Server中取消服务的注册
     * Shuts down Eureka Client. Also sends a deregistration request to the
     * eureka server.
     */
    @PreDestroy
    @Override
    public synchronized void shutdown() {
        if (isShutdown.compareAndSet(false, true)) {
            logger.info("Shutting down DiscoveryClient ...");
			//1.移除掉服务状态监听器
            if (statusChangeListener != null && applicationInfoManager != null) {
                applicationInfoManager.unregisterStatusChangeListener(statusChangeListener.getId());
            }
			//2.注销定时任务
            cancelScheduledTasks();

            // If APPINFO was registered
            //如果开启了shouldUnregisterOnShutdown 取消注册(默认true),
            if (applicationInfoManager != null
                    && clientConfig.shouldRegisterWithEureka()
                    && clientConfig.shouldUnregisterOnShutdown()) {
                    //3.修改实例的注册状态为 DOWN
                applicationInfoManager.setInstanceStatus(InstanceStatus.DOWN);
                //4.取消注册
                unregister();
            }

			//5.注销eurekaTransport
            if (eurekaTransport != null) {
                eurekaTransport.shutdown();
            }
			//6.注销心跳状态监视器
            heartbeatStalenessMonitor.shutdown();
            //7.注销注册表状态监视器
            registryStalenessMonitor.shutdown();

            logger.info("Completed shut down of DiscoveryClient");
        }
    }
	//注销定时任务
    private void cancelScheduledTasks() {
        if (instanceInfoReplicator != null) {
            instanceInfoReplicator.stop();
        }
        if (heartbeatExecutor != null) {
            heartbeatExecutor.shutdownNow();
        }
        if (cacheRefreshExecutor != null) {
            cacheRefreshExecutor.shutdownNow();
        }
        if (scheduler != null) {
            scheduler.shutdownNow();
        }
    }
    //注销EurekaTransport ,
	private static final class EurekaTransport {
        private ClosableResolver bootstrapResolver;
        private TransportClientFactory transportClientFactory;

        private EurekaHttpClient registrationClient;
        private EurekaHttpClientFactory registrationClientFactory;

        private EurekaHttpClient queryClient;
        private EurekaHttpClientFactory queryClientFactory;

        void shutdown() {
            if (registrationClientFactory != null) {
                registrationClientFactory.shutdown();
            }

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

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

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

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

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


总结一下,在shutdown方法中做了如下事情

  • 通过 applicationInfoManager.unregisterStatusChangeListener移除服务实例状态监听器StatusChangeListener
  • 调用DiscoveryClient.cancelScheduledTasks();取消定时任务
  • 修改applicationInfoManager.setInstanceStatus(InstanceStatus.DOWN);状态为DOWN,调用unregister方法取消注册
  • eurekaTransport.shutdown(); 注销和EurekaServer交互的Http客户端
  • 注销心跳状态监视器,注册表状态监视器

我们重点跟踪一下 unregister方法源码

    /**
    	向eureka发送取消注册请求
     * unregister w/ the eureka service.
     */
    void unregister() {
        // It can be null if shouldRegisterWithEureka == false
        if(eurekaTransport != null && eurekaTransport.registrationClient != null) {
            try {
                logger.info("Unregistering ...");
                //向eureka发送取消注册的http请求
                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);
            }
        }
    }

这里依然通过eurekaTransport.registrationClient得到EureakHttpClient客户端发请求,最终会调用AbstractJerseyEurekaHttpClient.cancel方法发送Delete取消注册请求

 @Override
    public EurekaHttpResponse<Void> cancel(String appName, String id) {
        String urlPath = "apps/" + appName + '/' + id;
        ClientResponse response = null;
        try {
            Builder resourceBuilder = jerseyClient.resource(serviceUrl).path(urlPath).getRequestBuilder();
            addExtraHeaders(resourceBuilder);
            //发送Delete请求
            response = resourceBuilder.delete(ClientResponse.class);
            return anEurekaHttpResponse(response.getStatus()).headers(headersOf(response)).build();
        } finally {
            if (logger.isDebugEnabled()) {
                logger.debug("Jersey HTTP DELETE {}/{}; statusCode={}", serviceUrl, urlPath, response == null ? "N/A" : response.getStatus());
            }
            if (response != null) {
                response.close();
            }
        }
    }

总结

  1. Eureak服务取消注册,通过 @PreDestroy标记DiscoveyClient.shutdown销毁方法,当容器正常关闭,Bean的销毁执行

  2. 在shutdown方法中注销了服务注册状态监听器,注销定时任务执行器,修改服务注册状态为下线,调用unregister方法取消注册等等

  3. unregister方法中通过eurekaTransport 得到HttpClient,使用AbstractJerseyEurekaHttpClient发送delete请求到Eureak Server取消服务注册

下一章推荐《Eureka Server 服务下线

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨家巨子@俏如来

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值