在看源码之前,先说一下标题中提到的三个概念:
1. 服务注册:
服务提供者(eureka客户端)在启动后,如果参数eureka.client.register-with-eureka为true,那么会将自己注册到服务注册中心中,注册的动作会将自己的元数据发送给注册中心,注册中心将接受的元数据保存在一个注册列表中,该列表是一个双层Map结构,具体为:Map<服务名, Map<实例名,服务实例>>
2. 服务续约:
成功注册的eureka服务(eureka客户端)会在注册之后维护一个心跳来告诉注册中心“我还活着”,这样注册中心就不会从注册列表中将这个服务实例剔除,关于这个心跳机制涉及到两个配置参数:
eureka.instance.lease-renewal-interval-in-seconds(默认30):心跳间隔时间
eureka.instance.lease-expiration-duration-in-seconds(默认90):定义服务失效时间
3. 服务获取:
前两个概念是针对服务提供者,而服务获取是针对服务消费者(也属于eureka客户端),即调用服务方才需要获取服务列表以便选择调用哪一个服务实例。在服务消费者启动后,会向服务注册中心请求一份服务清单,该清单记录了已经注册到服务中心的服务实例。该请求动作不会仅限于启动的时候,因为消费者需要访问正确的、健康的服务实例,因此会定时发送请求。间隔时间通过配置参数:
eureka.instance.registry-fetch-interval-seconds(默认30)
那么接下来我们来简单看一下源码:
首先eureka客户端最重要的功能实现类就是org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient
这个类是对Eureka发现法务的封装,而SpringCloudEureka本身就是对NetflixEureka的功能封装,因此,EurekaDiscoveryClient类会持有一个com.netflix.discovery.EurekaClient.EurekaClient对象引用(为组合关系,具体实现是NetflixEureka的DiscoveryClient类),而SpringCloudEureka本身有一个对发现服务的常用方法的抽象,这就是org.springframework.cloud.netflix.eureka.DiscoveryClient接口,EurekaDiscoveryClient实现了该接口(为继承关系),他们的关系大概如下图所示:
其中左边的两个是SpringCloudEureka的,右面的两个是NetflixEureka的。
既然服务发现的方法主要在Netflix的DiscoveryClient类中,可以看一下这个类的注释,主要告诉我们DiscoveryClient的主要功能:Eureka客户端的注册、续约、取消租约(服务关闭)、获取服务。
因此首先研究的就是它,在构造器中,DiscoveryClient会调用一个initScheduledTasks()方法,从命名就可以看出这是一个初始化方法,那么我们可以从这个方法入手,源码如下:
/**
* Initializes all scheduled tasks.
*/
private void initScheduledTasks() {
if (clientConfig.shouldFetchRegistry()) { // #1
// registry cache refresh timer
int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();
int expBackOffBound =