Eureka源码学习

最近学习的一点点内容,做个记录

Eureka源码学习(一):

1 为什么一个服务可以成为注册中心

创建一个Maven项目 之后创建一个Module 名为cloud-eureka的springboot项目 导入

在这里插入图片描述

该jar包,该module就成为了eureka服务中心,为什么呢?

解答:

因为该jar包通过依赖导入了另一个jar包如图:

在这里插入图片描述

该jar包下有个spring.factories文件
在这里插入图片描述

该文件的内容如图:

在这里插入图片描述

这就是springboot的自动配置导入了EurekaServerAutoConfiguration

在这里插入图片描述

在这里插入图片描述

其上面有@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)

意味着该配置类在有EurekaServerMarkerConfiguration.Marker这个类时才会加载

那什么时候才能有呢???

我们回归到该启动类上的注解@EnableEurekaServer

在这里插入图片描述

点进去该注解:

在这里插入图片描述

发现其导入了EurekaServerMarkerConfiguration这个类 ,再点进去

在这里插入图片描述

发现其创建了一个Marker类 即有了

EurekaServerMarkerConfiguration.Marker

那么当这个服务的启动类启动时 由于@EnableEurekaServer注解 创建了 开关类 (EurekaServerMarkerConfiguration.Marker)

相当于打开了一个开关,所以EurekaServerAutoConfiguration加载了 该服务就成为了Eureka注册中心。

总结 就是

@SpringBootApplication
@EnableEurekaServer

在这里插入图片描述

这两个注解和一个依赖配合 使一个服务成为了 Eureka注册中心。

2:一些知识

Eureka的一生

在这里插入图片描述

**1:**不满足强一致性的一个证据

在这里插入图片描述

Eureka自动配置类导入了一个初始化配置 点进去

在这里插入图片描述

在这里插入图片描述

因为实现了SmartLifecycle接口,SmartLifecycle继承了Lifecycle接口所以要重写start方法

点contextInitialized进去 会发现下面

在这里插入图片描述

初始化Eureka环境,初始化Eureka服务上下文

点进去

在这里插入图片描述

这一句 就是从其他peer(Eureka别的节点)拉取注册表 这也是Eureka不满足强一致性(C)的一个证据。

因为 节点1,启动时会拉取其他节点的注册表,但是如果之后有服务注册到其他节点, 节点1 就不能立即获取了

2: 剔除服务逻辑

紧接上面,点它下面那个

在这里插入图片描述

在这里插入图片描述

点这个postInit()

在这里插入图片描述

这个EvictionTask是这个定时任务 间隔时间为在这里插入图片描述

点进去

在这里插入图片描述

在这里插入图片描述

其中的逻辑为

在这里插入图片描述
在这里插入图片描述

3:初始化缓存

还是在最初的起点,进入EurekaAutoConfiguration 搜索 eurekaServerContext方法

在这里插入图片描述

进入DefaultEurekaServerContext

在这里插入图片描述

再进入这个初始化方法中

在这里插入图片描述

在这里插入图片描述

缓存就是在这个方法里面初始化的

在这里插入图片描述

4:对eureka server的所有操作,都是通过http请求完成的

server :

1:接受注册

2 :接受心跳

3:下线

4:获取注册列表

5:集群同步

在这里插入图片描述

5:集群同步

全局搜索ApplicationResource 再在里面搜索 addInstance

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

 if (this.peerEurekaNodes == Collections.EMPTY_LIST || isReplication) {
     //如果集群节点不是空 或者 isReplication为true
                return;
            }

意思就是同步过一次就不同步了

在这里插入图片描述

服务B注册到serverB ,serverB会跟serverA同步,但serverA不会跟serverC同步

6:recentlyChangedQueue什么时候清除数据

在这个AbstractInstanceRegistry里 有个属性 recentlyChangeQueue是用来存储最近改变的信息的(三分钟)

在这里插入图片描述

再在里面找AbstractInstanceRegistry的构造函数

在这里插入图片描述

在构造函数里有个方法 点进去

在这里插入图片描述

这个就是他剔除数据的条件

在这里插入图片描述

7:EurekaController

在EurekaServerAutoConfiguration 里有个 eurekaController,Eureka界面的信息都是从这里面来的

在这里插入图片描述

在这里插入图片描述

点进去有个staus方法,再依次点圈部分

在这里插入图片描述

进去 getStatusInfo()方法

在这里插入图片描述

3:Eureka的特点:

一:Eureka的CAP

1:C:Consistency(强一致性)

Eureka只能保证最终一致性,不能保证强一致性。所以它是弱一致性。

Eureka是默认开启一级缓存的(下面优化有介绍),二级缓存与注册表之间是强一致性同步更新,而二级与一级之间默认是30s,所以不能保证强一致性。

2:A:Availability(可用性)(这个帖子很详细)

众所周知,eureka采用的是AP模式,实现高可用最好的方式就是利用最少三台eureke server实例,实现两两之间的服务注册。从而达到同步数据的目的 那么这就涉及到如下的方面

  • eureka client和eureka server之间如何进行通信

    通过查询各种资料并追踪自动配置类发现,eureka和eureka之间的通信是采用类似springmvc的Jersey框架暴露接口进行通信的。通信的形式基本类似于我们使用http进行请求的方式。在EurekaServerAutoConfiguration中通过注入FilterRegistrationBean实现了在filter中加入包含了指定包名下的所有的Jersey的外部接口(??????如何理解

  • eureka注册在客户端和服务端分别怎么操作实现可用性的(心跳机制)

  • eureka续约/心跳在客户端和服务端分别怎么操作实现可用性的

  • eureka下线是怎么操作

3:P:Partition Tolerance(分区容错性)

分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性或可用性的服务。

​ Eureka在设计时就优先保证可用性,因此在设计时,Eureka 各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余节点依然可以提供注册和查询服务,而Eureka的客户端在向某个Eureka 注册或发现连接失败,则会自动切换至其他节点,只要有一台Eureka在,就能保证注册服务的可用性,只不过查到的信息不是最新的(不保证强一致),除此之外,Eureka还有一种自我保护机制,如果15分钟内超过85%的节点都没有正常的心跳,那么Eureka 就认为客户端与注册中心出现了网络故障,此时会出现一下几种情况:
1.Eureka 不在从注册列表中移除因为长时间没收到心跳而应该过期的服务
2.Eureka 仍能够接受新服务的注册和查询请求,但是不会同步到其他节点
3.网络稳定是,当前实例新的注册信息会同步到其他节点中
因此 Eureka 可以很好的应对网络故障导致部分节点失去联系的情况,而不是像zookeeper那样导致整个注册服务瘫痪

4:Eureka的优化:

一:Eureka的自我保护机制

一、初步认识Eureka
首先,Eureka服务注册与发现分为两个端:一个Eureka Client、一个Eureka Server,其实在Eureka Server注册中心集群条件下Eureka Server既是客户端也是服务端,相辅相成的,客户端就好比之前章节讲到的会员服务和订单服务,在Eureka Client启动的时候,会把当前的服务信息注册到Eureka Server上,默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个客户端服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,客户端服务实例与Eureka Server之间无法正常通信,而客户端服务实例本身是正常运行的,只是因为网络不用而Eureka Server无法接收心跳包而已,此时不应该移除这个微服务,所以引入了自我保护机制,这是Eureka服务注册与发现中心所读独有的特性,像其他常见的注册中心Zookeeper、Consul没有。

在这里插入图片描述

二、什么是Eureka保护机制

  1. 官方解释: 自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。

  2. 我的理解: 默认情况下,Eureka Client会定时的向 Eureka Server端发送心跳包,默认是30s发送一次,目的是告诉 Eureka Server当前客户端实例还处于存活状态,如果Eureka server在一定时间内没有收到实例的心跳,便会把该实例从注册表中删除(默认是90秒),但是,如果短时间内丢失大量的实例心跳,便会触发Eureka server的自我保护机制的 ,默认自我保护机制处于开启状态,比如在开发测试时,需要频繁地重启微服务实例客户端,但是我们很少会把eureka server一起重启(因为在开发过程中不会修改eureka注册中心),当一分钟内收到的心跳数大量减少时,会触发该保护机制。可以在eureka管理界面看到Renews threshold和Renews(last min),当Renews(last min)(最后一分钟收到的心跳数)小于Renews threshold(心跳阈值)的时候,如果某个服务实例宕机掉,触发保护机制,会出现红色的警告:

Renews threshold = count * 2 * renewal-percent-threshold

//count是服务的注册数量,2是因为每30s一个心跳。
//renewal-percent-threshold 就是配置的自我保护阈值参数(比例)

在这里插入图片描述

三、Eureka保护机制的目的

为了防止在一定时间内,Eureka ClientEureka Server在网络不同的情况下,Eureka Server误将Eureka Client服务剔除,这个机制是为了对服务进行保护;

四、如何关闭Eureka自我保护机制

在这里插入图片描述

Eureka自我保护机制默认是开启的,如果如果需要关闭自我保护机制,按照下述方式: enable-self-preservation: false 开关关闭掉,然后修改客户端和服务端相关参数,保证异常服务能及时剔除;

1.Eureka Server配置

注册中心关闭自我保护机制,修改检查失效服务的时间,以确保注册中心将不可用的实例及时正确剔除

  #Eureka自我保护机制
  server:
    #关闭eureka自我保护机制false(默认为true)
    enable-self-preservation: false
        
    # 配置Eureka Server清理无效节点的时间间隔(单位毫秒,默认60*1000毫秒,即60秒)
    eviction-interval-timer-in-ms: 2000
        
    # 自我保护阈值
    renewal-percent-threshold: 0.85
        
    #驱逐计时器扫描失效服务的间隔时间(默认为60*1000ms)
    eviction-interval-timer-in-ms: 1000 
        
	 #一级缓存设置(默认为true) 关闭从ReadOnlyCacheMap读注册表
    use-read-only-response-cache: false
        
    #ReadWriteCacheMap与ReadOnlyCacheMap之间的信息同步(如果开启一级缓存得到话会首先访问ReadOnlyCacheMa)默认是30*1000ms
    response-cache-update-interval-ms: 1000                  

注意

eureka.server.eviction-interval-timer-in-ms=5000 修改驱逐计时器扫描失效服务间隔时间后,运行日志可以看到现在每隔 5 秒 EvictionTimer 就会执行一次(以前默认是1分钟才执行一次)。

eureka.server.eviction-interval-timer-in-ms 不建议修改,因为即使即使修改了,哪怕是 每隔 1s 执行一次,当手动关闭 Eureka Client 后,注册中心也并不会立马注销此节点,同样要等到约 90 秒左右收不到客户端心跳才会将其移除
为什么要写上 ?

因为源码里是用Timer写的 但是 多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获异常,其他任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题

2.Eureka Client配置

减短客户端服务发送服务心跳给服务端的时间, 在开发测试时,将值设置设置小些,保证服务关闭后注册中心能及时踢出服务

    #表示eureka client间隔多久去拉取服务器注册信息,默认为30秒
    registry-fetch-interval-seconds: 10
##心跳检测与续约时间(测试环境和本地开发环境将值设置小一点,保证服务关闭后,注册中心能够及时踢出)
  instance:
    #eureka客户端需要多长时间发送心跳给eureka服务端,单位为秒(默认为30s),(客户端会按照此规则向Eureka服务端发送心跳检测包)
    lease-renewal-interval-in-seconds: 2
    #eureka服务端在接受到实例的最后一次发出的心跳后,需要等待多久才可以将此实力删除,单位为秒(默认为90s),超过时间则剔除(客户端会按照此规则向Eureka服务端发送心跳检测包)
    lease-expiration-duration-in-seconds: 2


五、开启和关闭Eureka保护机制的场景

Eureka Server和Eureka Client默认是开启自我保护机制

1.开发环境关闭

当我们在使用微服务框架做项目开发的时候,如果注册中心是Eureka,因为会频繁的重启本地开发环境,调试和修改代码,但是不会频繁的重启Eureka Server,所以建议在测试环境、本地开发环境时关闭Eureka的自我保护机制,,如果触发了保护机制,则旧的服务实例没有被删除,这时请求有可能跑到旧的实例中,而该实例已经关闭了,这就导致请求错误,影响开发测试效率;

2.生产环境开启

在微服务各个节点部署到生产环境了之后,建议开启Eureka自我保护环境,这一点还是比较重要的,因为在生产环境,并不会频繁的重启,而且有时在短时间内可能会发生服务与服务之间网络故障、重启Eureka Client客户端服务实例等其他原因导致通讯中断,所以一定要把自我保护机制打开,否则网络一旦终端,就无法恢复,导致误删除服务节点,造成生产故障;

六:防止服务压力过大

在这里插入图片描述

源码中 当第一个服务挂了 才会拉取后面的服务 ,在生产中,如果服务很多 数据量很大就会造成第一个服务压力过大,所以应该将后面的Url随机打乱 避免服务器过载的情况。

5:总结

一:服务端的总结:

在这里插入图片描述

二:客户端的总结:

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值