前提说明,本文跟踪的Eureka版本信息为:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>Hoxton.SR8</version>
</dependency>
1. 客户端加载方式
如果我们的应用仅仅只是springboot应用,只要我们的classpath目录下,有Netfilx和Eureka的核心包,咱们就可以在启动类上使用@EnableEurekaClient注解,来连接Eureka服务端。如图
如果咱们使用的是springcloud,咱们只需要依赖spring-cloud-starter-netflix-eureka-client这个包,应用就可以自动注册到Eureka服务端了(其原理就是通过springboot的@EnableAutoConfiguration自动配置实现的)。
2.源码加载入口
但凡是基于springboot作自动配置的,也就是通过@EnableAutoConfiguration注解进行加载,入口都在对应的starter中:
以服务端为例:spring-cloud-starter-netflix-eureka-server。
而它又会依赖到spring-cloud-netflix-eureka-server,在其目录下的META-INF包中,找spring.factories文件,里面就有我们要找的自动配置类:
同理,客户端加载入口如图:
以客户端为例:
3.client端源码解析
在客户端的配置类EurekaClientAutoConfiguration中我们可以看到,客户端加载的内容主要包括以下内容:
1. Eureka客户端配置信息初始化。
2.Eureka实例配置信息的初始化。
3.Eureka客户端对象CloudEurekaClient实例化:RefreshableEurekaClientConfiguration#eurekaClient;以及销毁时,调用shutdown()方法。
以上第3点,也即这段
CloudEurekaClient cloudEurekaClient = new CloudEurekaClient(appManager, config, this.optionalArgs, this.context);
是我们客户端初始化的核心入口。
跟踪其构造方法:
在这个方法中,核心任务有三个:
1.拉取注册中心的应用实例列表;
2.注册服务;
3.启动线程池分别进行:定时发送心跳、定时刷新本地应用实例列表、定时刷新实例信息。
3.1 拉取注册中心的应用实例列表
代码往下走,可以看到当配置eureka.client.fetchRegistry = true时,就会以下执行方法,去拉取实例注册表。
com.netflix.discovery.DiscoveryClient#fetchRegistry
com.netflix.discovery.DiscoveryClient#getAndStoreFullRegistry
com.netflix.discovery.shared.transport.jersey.AbstractJerseyEurekaHttpClient#getApplications
com.netflix.discovery.shared.transport.jersey.AbstractJerseyEurekaHttpClient#getApplicationsInternal
可以看到,客户端是通过Jersey框架,向Eureka服务端发起请求。当查询成功后,将其放入localRegionApps这个原子引用类中。
3.2 注册服务
回到梦开始的地方,继续往下可以看到465这行,调用方法
com.netflix.discovery.DiscoveryClient#register
同样通过jersey框架,发起post请求进行注册,请求成功返回true,如果请求失败,则抛出异常,也即应用启动失败。
3.3 启动线程池
回到梦开始的地方+1(其实就在下面不远),执行方法初始化定时任务
com.netflix.discovery.DiscoveryClient#initScheduledTasks
当然,这些线程池的初始化工作,需要回到“梦开始的地方”的上面几行(397)
3.4 服务取消
在CloudEurekaClient对象初始化时,指定了其销毁方法shutdown(),该方法由其父类实现。
其中com.netflix.discovery.DiscoveryClient#unregister方法,则是调用服务端的取消接口,将其从服务列表中剔除。