Zookeeper使用 多进程 unity 人脸识别 后端面试 xamarin mvvm replace eking文件 drupal7 vue学习 vue插件库 郑州普通话考试 jq选择子元素 jquery通过class获取元素 jquery获取下一个元素 hadoop源码 coreldraw学习 java运行软件 matlab中如何定义函数 idea开发python python正则 python集合操作 python安装mysql python配置 python中index的用法 python变量类型 random函数用法 java编程基础 java当前时间 java游戏开发 kafka中文教程 qtp下载 圆形截图 易语言多线程 pr黑场过渡 java语言程序设计 dnf刷什么图赚钱 流程图工具 汽车配件查询软件
当前位置: 首页 > 学习教程  > 编程语言

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

2020/8/31 14:30:22 文章标签:

取消注册

取消注册(服务下线)指的是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取消服务注册


本文链接: http://www.dtmao.cc/news_show_150226.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?