架构
Eureka Server:注册中心服务端
- 服务注册
- 提供注册表
- 同步状态
Eureka Client:注册中心客户端
- Register: 服务注册
- Renew: 服务续约
- Eviction 服务剔除
- Cancel: 服务下线
- GetRegisty: 获取注册列表信息
- Remote Call: 远程调用
、
工作流程
- Eureka Server 启动成功,等待服务端注册。在启动过程中如果配置了集群,集群之间定时通过 Replicate 同步注册表,每个 Eureka Server 都存在独立完整的服务注册表信息
- Eureka Client 启动时根据配置的 Eureka Server 地址去注册中心注册服务
- Eureka Client 会每 30s 向 Eureka Server 发送一次心跳请求,证明客户端服务正常
- 当 Eureka Server 90s 内没有收到 Eureka Client 的心跳,注册中心则认为该节点失效,会注销该实例
- 单位时间内 Eureka Server 统计到有大量的 Eureka Client 没有上送心跳,则认为可能为网络异常,进入自我保护机制,不再剔除没有上送心跳的客户端
- 当 Eureka Client 心跳请求恢复正常之后,Eureka Server 自动退出自我保护模式
- Eureka Client 定时全量或者增量从注册中心获取服务注册表,并且将获取到的信息缓存到本地
- 服务调用时,Eureka Client 会先从本地缓存找寻调取的服务。如果获取不到,先从注册中心刷新注册表,再同步到本地缓存
- Eureka Client 获取到目标服务器信息,发起服务调用
- Eureka Client 程序关闭时向 Eureka Server 发送取消请求,Eureka Server 将实例从注册表中删除
自我保护机制
Eureka在运行期间会统计心跳失败的比例,在15分钟内是否低于85%,如果出现了低于的情况,Eureka Server会将当前的实例注册信息保护起来,同时提示一个警告,表明进入了保护模式
一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据。也就是不会注销任何微服务
健康检查
eureka:
instance:
lease-renewal-interval-in-seconds: 30 # 表示 eureka client 发送心跳给server端的频率。这个值决定了服务注册的快慢,太快消耗资源。默认30秒。
lease-expiration-duration-in-seconds: 90 # 表示 eureka server 至上一次收到 client 的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该 instance。默认90秒 。 上报 eureka server 如何对待改 instance
client:
healthcheck:
enabled: true # 开启客户端健康检查
多级缓存机制
Eureka的注册表拉取机制分为了两种,第一种是第一次拉取服务注册表的时候,此时需要全量拉取注册表,将所有服务的注册表信息全部存放起来,第二种是每隔30秒,增量拉取服务注册表
在eureka client拉取注册表的时候,就会用到所谓的多级缓存机制,多级缓存机制中有两个缓存,一个叫只读缓存ReadOnlyCacheMap,一个叫读写缓存ReadWriteCacheMap。eureka client拉取注册表的时候,会先从ReadOnlyCacheMap中去获取注册表数据,如果获取不到的话再去ReadWriteCacheMap中找,如果还是找不到的话,就会通过ClassLoader的load方法直接从注册表获取数据再返回
多级缓存机制有多种过期策略
- 主动过期:当服务实例发生注册、下线、故障的时候,ReadWriteCacheMap中所有的缓存过期掉
- 定时过期:readWriteCacheMap在构建的时候,指定了一个自动过期的时间,默认值就是180秒,所以你往readWriteCacheMap中放入一个数据,180秒过后,就将这个数据给他过期了
- 被动过期:默认是每隔30秒,执行一个定时调度的线程任务,对readOnlyCacheMap和readWriteCacheMap中的数据进行一个比对,如果两块数据是不一致的,那么就将readWriteCacheMap中的数据放到readOnlyCacheMap中来
通过过期的机制,可以发现一个问题,就是如果ReadWriteCacheMap发生了主动过期或定时过期,此时里面的缓存就被清空或部分被过期了,但是在此之前readOnlyCacheMap刚执行了被动过期,发现两个缓存是一致的,就会接着使用里面的缓存数据
所以可能会存在30秒的时间,readOnlyCacheMap和ReadWriteCacheMap的数据不一致
区域配置
- region:可以简单理解为地理上的分区。比如亚洲地区,或者华北地区,再或者北京地区等等,没有具体大小的限制,根据项目具体的情况,可以自行划分region。
- zone:可以简单理解为 region 内的具体机房,比如说 region 划分为华北地区,然后华北地区有两个机房,就可以在此 region 之下划分出 zone1、zone2 两个 zone
eureka:
client:
# 尽量向同一区域的 eureka 注册,默认为true
prefer-same-zone-eureka: true
#地区
region: huabei
availability-zones:
huabei: zone-1,zone-2
service-url:
zone-1: http://localhost:30000/eureka/
zone-2: http://localhost:30001/eureka/
重试机制
Eureka 实现的服务治理机制强调了 CAP 原理中的 AP
spring:
cloud:
loadbalancer:
retry:
enabled: true # 开启Spring Cloud的重试功能
service: #负载均衡规则的配置
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #规则:随机________默认:轮循
ConnectTimeout: 250 # Ribbon的连接超时时间
ReadTimeout: 1000 # Ribbon的数据读取超时时间
OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
MaxAutoRetries: 1 # 对当前实例的重试次数
Eureka 集群
只需要在注册中心的配置文件中配置其他注册中心的地址,配置属性如下:
eureka.client.service-url.defaultZone
注册中心收到注册信息后会判断是否是其他注册中心同步的信息还是客户端注册的信息,如果是客户端注册的信息,那么他将会将该客户端信息同步到其他注册中心去;否则收到信息后不作任何操作。通过此机制避免集群中信息同步的死循环。