Spring Cloud学习笔记——Eureka的基本架构和心跳机制
Spring Cloud版本:Hoxton.SR3
Spring boot版本:2.2.5.RELEASE
demo Git仓库:开源在gitee中,私信索取地址
数据一致性
当聊到集群的时候,就无法不提到数据一致性的问题,那么,我们就以Eureka的Server集群为例,聊一聊集群中的数据一致性问题,并试图剖析Eureka集群的底层原理。初学者可跳过此篇。
分布式下,有一个著名的CAP原则。C指数据一致性,A指服务可用性,P则是分区容忍性。CAP三者,最多可得其二。如在单点服务中,由于不存在分区,则可达到CA。而在分布式服务里,基于分布式本身的特性,服务存在于多个服务中,依靠网络连接。在这种情况下,由于网络延迟等原因,分区是必然存在的。也就是说,在分布式下,P必然存在,任何集群都需要在C和A中做选择。
在这样的背景下,根据选择的不同,集群服务可能是AP的,也可能是CP的。如果是AP的,则集群允许在段时间里,各节点的数据出现不一致的情况,但是集群整体服务保持可用。如果是CP的,则集群在各节点数据不一致的段时间里,整体服务是不可用的,需要等待可节点数据同步到一致,再恢复可用状态。
需要理解的是,无论是AP还是CP,对于客户端来说,可能感知并不是很强烈。在AP情况下,客户端的感知可能是服务存在一定延迟,响应较慢,而不是服务不可用。在CP情况下,客户端一般来说对数据的更新是不敏感的。即客户端并不需要过分及时的取得最新的数据,也可以正常完成服务。
Eureka的AP
在AP和CP之间,Eureka选择的AP。即在数据不致的情况下,也允许客户端服务。我们尝试分析下,Eureka这种做法的理由是什么?
在分布式微服务架构中,基本角色有三种,分别是生产者,消费者,注册中心。生产者对外提供服务,消费者使用生产者的服务,而注册中心则承担一个中间人角色,维护生产者服务列表数据,并在消费者需要的时候提供给消费者。
在Eureka架构中,EurekaServer就是一个注册中心的角色。在EurekaServer中,存放的主要数据就是生产者服务列表,在需要的时候,将其提供给消费者。
所以,Eureka选择AP的理由是:
Eureka的功能专注于服务注册和发现,不会出现数据的竞态。
数据竞态指的是:在同一时间点,有多个线程竞争同一数据。
我们来了解一下Eureka的基本架构,分析为何不会出现数据竞态。架构图如下:
Eureka的基本架构
由架构图,可以得到以下几点:
Eureka Server各节点之间通过复制来同步数据。生产者向Eureka Server中的任一节点注册数据。消费者向Eureka Server中的任一节点获取数据。(事实上,Eureka架构中,并没有严格区分生产者、消费者,二者通常是一体的)消费者根据取得的生产者列表直接向任一生产者发起服务调用,如失败,可选择向其他生产者再次调用。基于以上:
每个client只会向一个server注册。每个server节点总是从其他服务中获取数据,用新的数据覆盖掉旧的数据。消费者从server节点中取得client列表,并缓存一份在本地,下次直接从本地获取。即使某个client宕机,导致某些server中的生产者列表不准确,此时,消费者可以根据需要进行重试。当server中的生产者列表发生变化时,会将变化向订阅的服务消费者发布,消费者就会更新本地缓存。综上,Eureka选择AP是可行的。事实上,由于注册中心仅承担服务注册与发现的功能,并且,消费者有失败重试,本地缓存,服务订阅等相关处理机制,这使得注册中心集群可以选择CP,也可以选择AP。Zookeeper选择的就是AP。
保持在线——心跳
在上面的部分,我们聊了Eureka的基本架构,理解了Eureka选择AP的理由。但是,有一个问题没有提到,即:server如何监测client的即时状态?
eureka通过心跳来监测client的状态。心跳,也是集群中常用的一种状态监测手段。那么,心跳是什么呢?
想象A、B两个人正在打电话,当B一段时间不说话时,A可能就会怀疑B是否还在电话旁,就会问:“你还在吗?”。这种情况,可以理解为是A主动发起了一个请求,去查询B的状态。事实上,B可以每隔一段时间,主动给A的个回应:“嗯……对……没错”。这样,A就会知道,B一直在,就不会猜也不会问了。
心跳正如打电话时的第二种状态:
client每隔一定时间,向server发送一个心跳(请求)。server每隔一段时间,检查所有client的心跳信息,当发现某个client长时间没有心跳,则认为该client下线。client再次上线后,会再次向server发送心跳。eureka里,client发送心跳的间隔时间默认为30秒,某client如果90秒内都没有心跳,则会被认为宕机。server默认每隔1分钟检查一次所有client的心跳信息。
配置项如下:
eureka配置