Eureka
注册中心提供:管理服务注册和发布、服务注册后如何被及时发现、服务宕机后如何及时下线、服务如何有效的水平扩展、服务发现时如何路由、服务异常时如何降级、注册中心如何实现自身高可用
Zk:
- leader(读写)+follower(读),leader主动同步数据到follower,保证顺序一致性,尽量保证数据一致,但是同步过程存在延时,可能存在短暂数据不一致,典型的CP
- leader崩溃时,为了保证数据一致性,尽量不要读到不一致的数据,会重新选举leader及数据同步,此时集群会短暂不可用
eureka:
- 多个节点都可以读写,节点之间异步复制数据,不能保证较强的一致性
- 任何一个节点宕机,都可以找其他节点注册和发现,可用性很高,但是会出现数据不一致,典型的AP
Eureka的缓存机制:
- Eureka Server的缓存是通过一个只读,一个读写缓存来实现的
- readWriteCacheMap : 当服务下线,过期,注册,状态变更,都会来清除读写缓存里面的数据。
- readOnlyCacheMap : 只读缓存,供客户端获取注册信息时使用,其缓存更新,依赖于定时器的更新,通过和readWriteCacheMap 的值做对比,如果数据不一致,则以readWriteCacheMap的数据为准。
二级缓存的作用:
- 优化并发读写的冲突,如果服务注册时同时有服务读取注册表信息,就会存在频繁读写加锁的操作,写的时候就不能读,导致性能下降,通过二级缓存避免大量读写都去操作一个表。大部分的读操作都走ReadOnly,只需要定时把ReadWrite缓存中的数据写入ReadOnly就好。
- 服务注册:注册会做三件主要的事,首次抓取全量注册表、向eureka server进行注册、初始化调度线程池,开启一些定时任务
底层原理分析:
- 抓取全量注册表:

2.向eureka server进行注册:

3.30S一次定时抓取增量注册表

服务续约:Eureka Client通过发送心跳续约,默认情况下每30秒发送一次心跳。

正常服务下线:Eureka Client优雅退出时会发送cancel命令,Eureka Server收到cancel命令时会删除该节点。

故障下线和server自我保护:server启动时会调度一个定时线程,60S检测一次client是否故障,然后进行故障下线判断

- 故障下线机制的问题:故障的时候,心跳的超时时间判断=当前时间是否大于上一次心跳时间+固定的90s间隔+两次调度的时间差(正常是60s)。同时在心跳时,更新上一次心跳时间也加了一个固定的90s。这导致实际的心跳时间跟过期时间差了180s,也就是可能90s就宕机了,但是要180s才算宕机,会导致实例故障后,没有及时下线。
- 解决:不应该有这个固定的90S,上次更新时间就应该是操作当前时间,然后判断的时候加上调度时间+固定间隔+调度时间差,同时加上摘取后要去修改缓存,缓存同步也有时间间隔。服务故障的实际下线时间会远大于所谓的90s感知。
- Eureka自我保护:
- 服务自身异常或服务与Eureka之前网络故障,导致Eureka Server收不到client的心跳
- 针对上述异常情况的安全保护措施,默认如果在15分钟内超过85%的客户端节点都没成功续约,Eureka就认为客户端与注册中心出现了网络故障,进入自我保护机制。Eureka Server不再从注册列表中移除因为长时间没收到续约而应该过期的服务,但仍能够接收新服务的注册和查询请求,并且不会同步数据到其他节点,保证当前节点依旧可用;网络稳定时,当前Eureka Server新的注册信息会被同步到其他节点、
- bug:自我保护机制,在计算期望心跳时,对实际的实例数量进行了*2。在摘除的时候没有去将期望心跳-2,这里导致了很多服务实例故障下线,摘除后,但是每分钟期望的心跳次数没有减少。实际的实例变少,导致实际心跳次数变少。如果较多服务实例故障被自动摘除,很快会快速导致eureka进入自我保护机制
- 自我保护机制的意义:
- 同时保留好数据与坏数据比丢掉任何数据要好,当网络故障恢复后,这个Eureka节点会退出自我保护模式
- Eureka有客户端缓存功能,即使集群中所有节点失效,还能保证客户端之间正常通信
- 微服务的负载均衡策略会自动剔除死亡的服务节点
eureka sever集群同步:集群启动数据同步、client注册/下线/心跳/故障时,集群数据同步。
- 集群启动: 作为client找任意一个sever进行注册和拉取注册表

- client注册/下线/心跳/故障:与通信的server进行续约,该server还需把信息同步给其他的server,server判断是client来的请求就代表要同步给其他server,如果是其他server来的,就只需要同步自身。

eureka sever集群同步任务批处理机制:同步请求不是直接发送给其他server,而是通过三重队列进行批处理

极端情况下多久才会读到最新的注册表:
- server刚执行完上一次心跳检测后,某个client宕机了,这时候下一次心跳检测间隔时间为60S
- 心跳的超时时间判断和心跳更新时一共叠加了两次默认的超时时间,心跳时间跟过期时间差了180s,才会判断为宕机
- 判断宕机后,更新注册表,过期读写缓存。client30s一次拉取增量注册表,如果缓存同步的定时任务已执行了,那么只读缓存就会有最新的注册表信息。如果缓存同步任务没有执行,那么会二级缓存找不到,会直接从增量注册表中获取到三分钟内的实例信息。
- 极端情况下的时间是:60+180+30=270s,四分半。
eureka集群特性:
- 多个节点都可以读写,节点之间异步复制数据,不能保证较强的一致性
- 任何一个节点宕机,都可以找其他节点注册和发现,可用性很高,但是会出现数据不一致,典型的AP
为什么有了Eureka Client还要用RestFul API:微服务的优势之一就是允许使用异构的技术,如果你有一个系统,一部分是Spring Cloud构建的,一部分是用其他语言写的,你希望两个不同语言应用之间的通信也能享受服务发现所带来的好处,此时就可编写一个基于另一种语言的Eureka Client,将应用也注册到Eureka Server!
本文来自博客园,作者:难得,转载请注明原文链接:https://www.cnblogs.com/zhangbLearn/p/18829314

浙公网安备 33010602011771号