Eureka服务注册源码学习

首先我们要知道 Eureka 2.0 闭源了,不过这其实影响不大,国内大部分的都还在使用Eureka 1.X 系列,所以适当的了解下Eureka的源码也是挺好的,就算之后不用,思想还是可以借鉴的。

总的来说,Eureka基本就做两件事,服务注册和服务发现,这里先学习下服务注册的源码逻辑

这里先简单介绍下用来测试源码的Eureka客户端和Eureka服务端配置

Eureka客户端配置:

server:
  #端口号
  port: 8763
eureka:
  client:
    service-url:
     #服务注册地址,这里填的是之前在Eureka Server配置的服务注册地址,只要有Eureka Client上线,就会向这个地址注册
      defaultZone: http://localhost:8761/eureka/
    fetch-registry: true
spring:
  application:
   #服务名
    name: eureka-client

Eureka服务端配置:

server:
  #端口号
  port: 8761
eureka:
  instance:
    #设置主机ip以及是否提交ip信息
    prefer-ip-address: true
    hostname: localhost
    service-url:
       #服务注册地址
       defaultZone: http://localhost:8761/eureka/
  client:
   #防止eureka-server向自己注册
    register-with-eureka: false
    fetch-registry: false
spring:
  application:
    name: eureka-server

服务注册

首先要找到相关的类,一般我们都会使用@EnableDiscoveryClient注解来做服务注册功能,让注册中心能够发现该服务。

  • 先看@EnableDiscoveryClient注解源码
    在这里插入图片描述
    这是一个注解类,红框里是这个类的关键作用描述,意思是用于开启一个DiscoveryClient实例,进入DiscoveryClient类,先看看它的构造方法,毕竟你要搞个实例出来,构造方法还是必要的

  • DiscoveryClient类的构造方法

 DiscoveryClient(ApplicationInfoManager applicationInfoManager, EurekaClientConfig config, AbstractDiscoveryClientOptionalArgs args,
                    Provider<BackupRegistry> backupRegistryProvider, EndpointRandomizer endpointRandomizer) {
        if (args != null) {
            this.healthCheckHandlerProvider = args.healthCheckHandlerProvider;
            this.healthCheckCallbackProvider = args.healthCheckCallbackProvider;
            this.eventListeners.addAll(args.getEventListeners());
            this.preRegistrationHandler = args.preRegistrationHandler;
        } else {
            this.healthCheckCallbackProvider = null;
            this.healthCheckHandlerProvider = null;
            this.preRegistrationHandler = null;
        }
.........
        // finally, init the schedule tasks (e.g. cluster resolvers, heartbeat, instanceInfo replicator, fetch(最后,初始化调度任务(例如,集群解析器、heartbeat、instanceInfo复制器、fetch)
        initScheduledTasks();
.........
        initTimestampMs = System.currentTimeMillis();
        logger.info("Discovery Client initialized at timestamp {} with initial instances count: {}",
                initTimestampMs, this.getApplications().size());
    }

最后会进入上面的方法里,代码太长占篇幅,我做了省略哈,可以发现有个 initScheduledTasks()方法,有个初始化作用,进去看看它

  • initScheduledTasks()方法源码,在这个方法里我们打上几个断点

第一个断点:

 // InstanceInfo replicator
            instanceInfoReplicator = new InstanceInfoReplicator(
                    this,
                    instanceInfo,
                    clientConfig.getInstanceInfoReplicationIntervalSeconds(),
                    2); // burstSize
 

在这里插入图片描述

可以看到里面的instanceInfo对象里的一些属性值和我们Eureka客户端配置文件里写的值是一样的

第二个断点:

instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());

这个断点用了instanceInfoReplicator.start()方法,猜测instanceInfoReplicator类要么实现了Runnable要么继承了Thread

  • 看下instanceInfoReplicator类的源码
class InstanceInfoReplicator implements Runnable {
 public void run() {
        try {
            discoveryClient.refreshInstanceInfo();

            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()的方法,断点跟进register()方法
在这里插入图片描述
通过这个断点方法,我们可以知道com.netflix.appinfo.InstanceInfo是入参,这是Eureka客户端的实例信息,然后通过REST请求方式来向Eureka服务端请求服务注册。

发布了136 篇原创文章 · 获赞 109 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_38106322/article/details/103769016