Spring Cloud Eureka源码分析(下)

四、服务续约


在DiscoveryClient中构造方法中initScheduledTasks,构建心跳任务,在HeartbeatThread中调用sendHeartBeat方法想请求ApplicationResource中GetInstanceInfo这个接口,会返回一个InstanceResource的实例,在该实例中定义了一个statusUpdate的接口来更新状态,InstanceResource.statusUpdate();在该方法中,我们重点关注 registry.statusUpdate 这个方法,它会调用


AbstractInstanceRegistry.statusUpdate来更新指定服务提供者在服务端存储的信息中的变化。在这个方法中,会拿到应用对应的实例列表,然后调用Lease.renew()去进行心跳续约。


Spring Cloud Eureka源码分析(下)


五、服务发现

我们继续来研究服务的发现过程,就是客户端需要能够满足两个功能


1. 在启动的时候获取指定服务提供者的地址列表

DiscoveryClient构造时进行查询构造方法中,如果当前的客户端默认开启了fetchRegistry,则会从eureka-server中拉取数据,如果第一次获取是以全量的形式获取,非第一次则以增量的形式获取数据。


2,Eureka server端地址发生变化时,需要动态感知


定时任务每隔30s更新一次本地地址列表


在DiscoveryClient构造的时候,会初始化一些任务,这个在前面咱们分析过了。其中有一个任务动态更新本地服务地址列表,叫 cacheRefreshTask 。这个任务最终执行的是CacheRefreshThread这个线程。它是一个周期性执行的任务,具体我们来看一


下。从整体上看,TimedSupervisorTask是固定间隔的周期性任务,一旦遇到超时就会将下一个周期的间隔时间调大,如果连续超时,那么每次间隔时间都会增大一倍,一直到达外部参数设定的上限为止,一旦新任务不再超时,间隔时间又会自动恢复为初始值。


CacheRefreshThread运行时会调用refreshRegistry()其中有两段主要逻辑,一段是判断remoteRegions是否发生了变化,变化则更新;二是调用fetchRegistry获取本地服务地址缓存,判断全量更新,还是增量更新,将本地缓存更新的事件广播给所有已注册的监听器,判断server端的成员变量是否与本地一致;如果不一致,则更新,并广播对应事件。


六,服务端查询地址流程


前面我们知道,客户端发起服务地址的查询有两种,一种是全量、另一种是增量。对于全量查询请求,


会调用Eureka-server的ApplicationsResource的getContainers方法。

而对于增量请求,会调用ApplicationsResource.getContainerDifferential。


七、Eureka自我保护机制


Eureka Server在运行期间会去统计心跳失败的比例在15分钟之内是否低于85% , 如果低于85%,


Eureka Server会认为当前实例的客户端与自己的心跳连接出现了网络故障,那么Eureka Server会把这


些实例保护起来,让这些实例不会过期导致实例剔除。

这样做的目的是为了减少网络不稳定或者网络分区的情况下,Eureka Server将健康服务剔除下线的问


题。 使用自我保护机制可以使得Eureka 集群更加健壮和稳定的运行。

进入自我保护状态后,会出现以下几种情况


Eureka Server不再从注册列表中移除因为长时间没有收到心跳而应该剔除的过期服务

Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上,保证当前


节点依然可用。



Spring Cloud Eureka源码分析(下)


这两个变量的更新

需要注意的是,这两个变量是动态更新的,有四个地方来更新这两个值:


Eureka-Server的初始化

PeerAwareInstanceRegistryImpl.cancel 服务下线的时候

PeerAwareInstanceRegistryImpl.register 服务注册的时候

PeerAwareInstanceRegistryImpl.scheduleRenewalThresholdUpdateTask 15分钟运行一次,判断在15分钟之内心跳失败比例是否低于85%。

,七,CAP模型


CAP 定理

分布式系统有三个指标:Consistency、 Availability、 Partition tolerance,它们的第一个字母分别是 C、A、P含义分别是一致性、可用性、分区容错,这三个指标不可能同时做到。这个结论就叫做 CAP 定理。


Zookeeper保证CP

zookeeper服务注册功能对可用性的要求要高于一致性。zk当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。


Eureka保证AP


Eureka在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。


Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:



Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务


Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)


当网络稳定时,当前实例新的注册信息会被同步到其它节点中


Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。


上一篇:Spring Cloud Hystrix


下一篇:Spring Cloud Open Feign源码分析(下)