Spring Cloud中的初步学习(三)

Spring Cloud中的初步学习(三)

一、Eureka与Zookeeper区别

Eureka与Zookeeper都可以作为注册中心使用,功能上区别主要根据CAP理论讨论:
C–Consistency(一致性):数据更新时,节点所有变动都是同步一致的
A–Availability(可用性):响应性能好,有请求就有响应,无论失败还是成功
P–Partition tolerance(分区容忍性):就算一部分信息丢失,也能提供持续服务。

注册中心查询服务列表时,返回的注册信息可以是几分钟之前的,但是服务不可用时在应用中是不能接受的,也就是说作为注册中心侧重AP。

Zookeeper侧重了CP:
Zookeeper出现的一种情况导致可用性不如Eureka-------当主节点与其他节点失去联系时,剩余节点选举leader,选举时间在30~120s,在选举时间内整个服务注册中心是不可用的。云部署时大概率会出现这种情况,可能会导致注册功能长期不能使用

Eureka侧重了AP:
Eureka能解决Zookeeper可用性的问题,在Eureka各个节点上,挂掉几个不会影响节点正常工作,剩余节点仍可以提供注册功能和查询服务。大概机制就是,在向某个Eureka注册或连接失败,会自动切换其他节点,只要有Eureka一个节点在,就能进行服务,但查询到的信息可能不是最新的,一致性不强。
Eureka还有一种保护机制,默认情况下开启。正常情况下,服务掉线会进行剔除,比例不大。但网络波动造成剔除条件达成,就会将正常服务的节点非正常剔除,超过15%以上的剔除就会触发保护机制,不会剔除任何服务实例,保证集群信息有效,仍可进行注册和查询,注册信息各节点可能不一致,网络稳定后,就会同步所有信息弥补一致性。
测试时关闭保护机制:配置文件中加入
eureka.server.enable-self-preservation=false

二、Eureka是如何进行注册和抓取

1、注册流程

eureka能实现动态管理和维护微服务信息

client客户端中工作原理:
客户端配置文件eureka.client相关属性执行客户端逻辑,配置信息如下

server.port=8091
#服务名称
spring.application.name=first-service
#client配置
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka,http://127.0.0.1:8762/eureka
#ip-preffer
eureka.instance.prefer-ip-address=true
  • 注册:客户端启动后,根据配置文件中service-url.defaultZone,找到地址中客户端对应的注册中心,,将客户端的信息通过http协议参数提交服务端,配置文件中register-with-eureka的值为true就是注册,false不注册。
  • 抓取(发现服务):客户端启动后运行每隔30s抓取server存储的client注册信息,fetch-registry属性为true就会自动抓取,false不抓取;还可以设置registry-fetch-interval重新定义时间间隔。
  • 心跳检测:也称为续约,每隔30s,client发送存活信息给server,更新server中注册信息的时间戳,通知server该client可提供服务;设置instance-info-replication-interval-seconds修改心跳时间。

值得注意的是,client端的选择是根据server端的就近原则,选择server端注册中心同一机房的client端,若同机房对应client宕机,根据负载均衡选择其他机房client端,默认round-robin轮询方式。

server服务端中工作原理:
服务端配置文件eureka.client相关属性执行客户端逻辑,配置信息如下

server.port=8761
#服务名称/功能名称
spring.application.name=eureka-server
#eureka客户端相关配置
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka
eureka.instance.prefer-ip-address=true
#关闭保护机制
#eureka.server.enable-self-preservation=false
  • 注册:接受请求,填写信息数据,注册信息为双层map—ConcurrentHashMap,在内存中维护此数据结构,
    ConcurrentHashMap<String,Map<String,Lease<InstanceInfo>>> -----> 这里简化成Map<str1,Map<str2,str3>>
    str1是服务名称—client配置文件中的spring.application.name;
    str2是—服务实例的id;
    str3是—Lease类,其中会维护每个服务最近一次的心跳时间,泛型是InstanceInfo,就是实例具体信息,如ip、hostname、端口号、时间戳等信息。
public abstract class AbstractInstanceRegistry implements InstanceRegistry {
    private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry
            = new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();
}
  • 服务剔除:server服务端每隔60s,检测一次客户端超时心跳发送间隔是否超过90s,超过则对客户端的注册信息剔除。剔除时,剔除比例超过15%就会触发保护机制。
  • 服务注销:server接收到client的cancel请求,注册信息中删除对应client信息;清空二级缓存;集群中服务器数量改变,保护机制中阈值随之发生变化;节点信息同步

2、Server端的多级缓存机制

server端存储的注册信息是在缓存中的,内存读写造成并发问题,所以使用多级缓存机制。

  • 一级缓存:本质是HashMap,没有过期时间,保留原有数据结构,readOnlyCacheMap
  • 二级缓存:guava缓存,包含失效机制,数据结构是LoadingCache,本质还是map结构,保留原有数据结构,readWriteCacheMap

client抓取注册表细节:在client端抓取服务时,会先从readOnlyCacheMap查询缓存的注册表;没有发现就查询readWriteCacheMap中的注册表;如果也没有,就从内存中获取client的注册信息,根据guava的load机制将原始请求的服务信息加工处理放进二级缓存readWriteCacheMap;server端中的TimerTask将二级缓存中数据同步到一级缓存,方法中包含了删除和更新。

注册表更新细节:server端中更新注册表,剔除过期的二级缓存readWriteCacheMap,不影响readOnlyCacheMap查询注册信息;默认30s之后将更新的注册信息更新到readOnlyCacheMap;30s之后后台线程发现readWriteCacheMap清空,也会清空readOnlyCacheMap。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值