(一)EurekaClient-服务实例注册、下架

0. 前言

  • springboot版本:2.1.9.RELEASE
  • springcloud版本:Greenwich.SR4

1. 服务实例注册

客户端触发注册的时机:

  • 客户端启动时发起注册,当配置文件配置了 eureka.client.should-enforce-registration-at-init = true ,不配置默认为 false
  • 客户端定期心跳续租时,向服务端发起心跳续租,服务端返回404,客户端立即发起注册
  • 客户端定期检查自身数据状态,当相关信息(数据中心、实例信息、健康状态)变更时,发起注册

2. register()

上面所有触发注册的情况,调用的都是 DiscoveryClient 类中的 register() 方法

// DiscoveryClient.class
boolean register() throws Throwable {
    logger.info(PREFIX + "{}: registering service...", appPathIdentifier);
    EurekaHttpResponse<Void> httpResponse;
    try {
        // 2.1 发起 Jersey 注册请求
        httpResponse = eurekaTransport.registrationClient.register(instanceInfo);
    } catch (Exception e) {
        logger.warn(PREFIX + "{} - registration failed {}", appPathIdentifier, e.getMessage(), e);
        throw e;
    }
    if (logger.isInfoEnabled()) {
        logger.info(PREFIX + "{} - registration status: {}", appPathIdentifier, httpResponse.getStatusCode());
    }
    // 服务端返回204,表示注册成功但没有返回数据
    return httpResponse.getStatusCode() == Status.NO_CONTENT.getStatusCode();
}
2.1 发起 Jersey 注册请求

Jersey 是一个 REST 框架,提供 JAX-RS 参考实现等。 Jersey 提供了自己的 API,这些 API 扩展了 JAX-RS 工具箱,并具有其他功能和实用程序,以进一步简化 RESTful 服务和客户端开发。 Jersey 还公开了许多扩展 SPI ,以便开发人员根据自身需求进行扩展。

// AbstractJerseyEurekaHttpClient.class
public EurekaHttpResponse<Void> register(InstanceInfo info) {
    String urlPath = "apps/" + info.getAppName();
    ClientResponse response = null;
    try {
        Builder resourceBuilder = jerseyClient.resource(serviceUrl).path(urlPath).getRequestBuilder();
        addExtraHeaders(resourceBuilder);
        // 通过 Jersey 提交 post 请求
        response = resourceBuilder
                .header("Accept-Encoding", "gzip")
                .type(MediaType.APPLICATION_JSON_TYPE)
                .accept(MediaType.APPLICATION_JSON)
                .post(ClientResponse.class, info);
        return anEurekaHttpResponse(response.getStatus()).headers(headersOf(response)).build();
    } finally {
        if (logger.isDebugEnabled()) {
            logger.debug("Jersey HTTP POST {}/{} with instance {}; statusCode={}", serviceUrl, urlPath, info.getId(),
                    response == null ? "N/A" : response.getStatus());
        }
        if (response != null) {
            response.close();
        }
    }
}

3. 服务实例下架

// DiscoveryClient.class
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);
            // 3.1 向服务端注销当前服务实例,发起下架
            unregister();
        }

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

        // 注销相关监控
        heartbeatStalenessMonitor.shutdown();
        registryStalenessMonitor.shutdown();

        logger.info("Completed shut down of DiscoveryClient");
    }
}
3.1 从服务端注销当前服务实例
// DiscoveryClient.class
void unregister() {
    // It can be null if shouldRegisterWithEureka == false
    if(eurekaTransport != null && eurekaTransport.registrationClient != null) {
        try {
            logger.info("Unregistering ...");
            // 发起 Jersey 下架请求,与上面注册类似
            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);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值