SpringCloud源码阅读2-Eureka客户端的秘密(下)

简介: SpringCloud源码阅读2-Eureka客户端的秘密(下)

2.1.4 InstanceInfoReplicator.run()

public void run() {
        try {
          //1.刷新DataCenterInfo
          //2.刷新LeaseInfo 租约信息
          //3.从HealthCheckHandler中获取InstanceStatus
            discoveryClient.refreshInstanceInfo();
      //如果isInstanceInfoDirty=true表明需要更新,返回dirtyTimestamp。
            Long dirtyTimestamp = instanceInfo.isDirtyWithTime();
            if (dirtyTimestamp != null) {
                discoveryClient.register();//注册。
                instanceInfo.unsetIsDirty(dirtyTimestamp);//注册完成,设置没有更新。
            }
        } catch (Throwable t) {
            logger.warn("There was a problem with the instance info replicator", t);
        } finally {
            Future next = scheduler.schedule(this, replicationIntervalSeconds, TimeUnit.SECONDS);
            scheduledPeriodicRef.set(next);
        }
    }

可以看出实例注册就在discoveryClient.register()

那么第一次注册发生在什么时候呢?

initScheduledTasks方法中,执行instanceInfoReplicator.start时,会首先调用instanceInfo.setIsDirty(),初始化是否更新标志位为ture ,开启线程,40秒后发起第一次注册。(当然如果在这40秒内,如果有状态变化,会立即发起注册。)


2.1.4 discoveryClient.register()

boolean register() throws Throwable {
        logger.info(PREFIX + "{}: registering service...", appPathIdentifier);
        EurekaHttpResponse<Void> httpResponse;
        try {
          //发起注册
            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());
        }
        return httpResponse.getStatusCode() == 204;
    }

可以看出,register方法本质也是通过eurekaTransport 来发起与server的通信的。


2.2EurekaClient卸载方法

2.2.1shutdown()

注解@PreDestroy修饰的shutdown()会在Servlet被彻底卸载之前执行。

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


3.EurekaAutoServiceRegistration回调


EurekaAutoServiceRegistration实现了SmartLifecycle,会在spring启动完毕后,调用其start()方法。

@Override
  public void start() {
    // 设置端口
    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());
      }
    }
    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);//
    }
  }

this.serviceRegistry.register(this.registration);

@Override
  public void register(EurekaRegistration reg) {
    maybeInitializeClient(reg);
    // 更改状态,会触发监听器的执行
    reg.getApplicationInfoManager()
        .setInstanceStatus(reg.getInstanceConfig().getInitialStatus());
    reg.getHealthCheckHandler().ifAvailable(healthCheckHandler ->
        reg.getEurekaClient().registerHealthCheck(healthCheckHandler));
  }


4.总结


1.注册流程

EurekaAutoServiceRegistration.start()

-->EurekaServiceRegistry.register(EurekaRegistration)

-->ApplicationInfoManager.setInstanceStatus 状态改变,

-->StatusChangeListener 监听器监听到状态改变

-->InstanceInfoReplicator.onDemandUpdate() 更新状态到server

-->InstanceInfoReplicator.run()

-->DiscoveryClient.register()

-->eurekaTransport.registrationClient.register(instanceInfo);

-->jerseyClient


2.客户端初始化的几个定时任务

  • 缓存刷新任务,默认30秒
  • 心跳任务,默认30秒
  • 信息更新任务,默认40秒


3.客户端的几个主要操作:

  • 服务注册(register)
  • 服务续约(renew)
  • 服务下线(unregister)
  • 服务获取(fetchRegistry)
  • 缓存刷新(refreshRegistry)

由于篇幅原因,很多细节不能一一展示。本文志在说说一些原理,具体细节可以研读源码,会发现框架真优秀啊。


相关文章
|
2月前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
191 0
|
2月前
|
SpringCloudAlibaba Java 网络架构
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
117 0
|
17天前
|
负载均衡 监控 容灾
【SpringCloud】详解Eureka注册中心
【SpringCloud】详解Eureka注册中心
23 0
|
17天前
|
Java Maven 微服务
第四章 Spring Cloud Netflix 之 Eureka
第四章 Spring Cloud Netflix 之 Eureka
14 0
|
17天前
|
Java Nacos 开发者
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
|
22天前
|
Java Maven Nacos
Spring Cloud Eureka 服务注册和服务发现超详细(附加--源码实现案例--及实现逻辑图)
Spring Cloud Eureka 服务注册和服务发现超详细(附加--源码实现案例--及实现逻辑图)
31 0
|
1月前
|
开发框架 负载均衡 Java
Spring boot与Spring cloud之间的关系
总之,Spring Boot和Spring Cloud之间的关系是一种构建和扩展的关系,Spring Boot提供了基础,而Spring Cloud在此基础上提供了分布式系统和微服务架构所需的扩展和工具。
21 4
Spring boot与Spring cloud之间的关系
|
2月前
|
SpringCloudAlibaba 负载均衡 Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(目录大纲)
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(目录大纲)
70 1
|
2月前
|
Java Nacos Sentinel
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(九)Nacos+Sentinel+Seata
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(九)Nacos+Sentinel+Seata
232 0
|
2月前
|
消息中间件 SpringCloudAlibaba Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(八)Config服务配置+bus消息总线+stream消息驱动+Sleuth链路追踪
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(八)Config服务配置+bus消息总线+stream消息驱动+Sleuth链路追踪
788 0