Spring Cloud Netflix 在设计 Eureka 时就紧遵AP原则(尽管现在2.0发布了,但是由于其闭源的原因 ,但是目前 Ereka 1.x 任然是比较活跃的)。
Eureka Server 也可以运行多个实例来构建集群,解决单点问题,但不同于 ZooKeeper 的选举 leader 的过程,Eureka Server 采用的是Peer to Peer 对等通信。这是一种去中心化的架构,无 master/slave 之分,每一个 Peer 都是对等的。在这种架构风格中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl 指向其他节点。每个节点都可被视为其他节点的副本。
在集群环境中如果某台 Eureka Server 宕机,Eureka Client 的请求会自动切换到新的 Eureka Server 节点上,当宕机的服务器重新恢复后,Eureka 会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会在节点间进行复制(replicate To Peer)操作,将请求复制到该 Eureka Server 当前所知的其它所有节点中。
当一个新的 Eureka Server 节点启动后,会首先尝试从邻近节点获取所有注册列表信息,并完成初始化。Eureka Server 通过 getEurekaServiceUrls() 方法获取所有的节点,并且会通过心跳契约的方式定期更新。
默认情况下,如果 Eureka Server 在一定时间内没有接收到某个服务实例的心跳(默认周期为30秒,30是发送心跳的频率),Eureka Server 将会注销该实例(默认为90秒, eureka.instance.lease-expiration-duration-in-seconds 进行自定义配置)。
当 Eureka Server 节点在短时间内丢失过多的心跳时,那么这个节点就会进入自我保护模式。
Eureka的集群中,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:
Eureka不再从注册表中移除因为长时间没有收到心跳而过期的服务;
Eureka仍然能够接受新服务注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用);
当网络稳定时,当前实例新注册的信息会被同步到其它节点中;
因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使得整个注册服务瘫痪。
Eureka的自我保护机制:
首先对Eureka注册中心需要了解的是Eureka各个节点都是平等的,没有ZK中角色的概念, 即使N-1个节点挂掉也不会影响其他节点的正常运行。
默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。
自我保护机制
官方对于自我保护机制的定义:
自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。
自我保护机制的工作机制是:如果在15分钟内超过85%的客户端节点没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制,此时会出现以下几种情况:
- Eureka Server不再从注册列表中移除因为长时间没收到心跳而应该过期的服务。
- Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用。
- 当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。
因此Eureka Server可以很好的应对因网络故障导致部分节点失联的情况,而不会像ZK那样如果有一半不可用的情况会导致整个集群不可用而变成瘫痪。
什么时候会触发自我保护机制:
当每分钟心跳数< n时,触发自我保护 实例化2续租百分比 0.85 =n
自我保护开关Eureka自我保护机制,通过配置 eureka.server.enable-self-preservation
来true
打开/false
禁用自我保护机制,默认打开状态,建议生产环境打开此配置。
自我保护机制的触发条件:
https://www.cnblogs.com/xishuai/p/spring-cloud-eureka-safe.html
https://blog.csdn.net/qq_38545713/article/details/105535950
Eureka-client启动的流程
- 读取和server的交互配置信息
- 去server端拉取注册信息,并 缓存到本地
- 服务注册,
- 有三个定时任务 定时发送心跳给server端维持 续约, 定期从 server拉取注册信息表更新本地缓存,监控自身变化,有变动去注册
集群模式:
如果开启了自我保护机制之后如果15分钟没有修复得好,然后剔除机制就会剔除
Eureka整体的 一个流程:
- 服务注册到EurekaServer注册列表中,并且每30s发送一次心跳续约
- 有一个线程会定时的去查看EurekaServer 每60秒检测心跳故障 心跳超时时间默认为90s
- EurekaServer会 集群之间进行信息同步
- 当有新的服务注册到EurekaServer的时候,会立马同步到二级缓存 readWriteCacheMap 180s后自动过期
- 二级缓存会有一个定时任务每30秒同步一次数据,将二级缓存同步到一级缓存
- 服务发现端 每隔30秒都会从一级缓存中拉取注册信息到本地缓存,client在增量同步注册表的时候 ,同步 获取了一个eureka server 全量注册表的hash值, 在client 增量同步注册表完成之后,会计算一个hash值,然后将自己计算出来的hash值和eureka server全量 注册表的hash值做对比,如果是一样的说明同步没有问题,否则重新拉取注册表