读时加写锁,写时加读锁,Eureka可真的会玩

本文深入探讨了Eureka服务注册中心在使用读写锁时的独特策略:读操作加写锁,写操作加读锁。通过对Eureka源码的分析,解释了这种设计背后的思考和原因,以及如何确保在并发场景下的数据一致性。
摘要由CSDN通过智能技术生成

在对于读写锁的认识当中,我们都认为读时加读锁,写时加写锁来保证读写和写写互斥,从而达到读写安全的目的。但是就在我翻Eureka源码的时候,发现Eureka在使用读写锁时竟然是在读时加写锁,写时加读锁,这波操作属实震惊到了我,于是我就花了点时间研究了一下Eureka的这波操作。

Eureka服务注册实现类

众所周知,Eureka作为一个服务注册中心,肯定会涉及到服务实例的注册和发现,从而肯定会有服务实例写操作和读操作,这是每个注册中心最基本也是最核心的功能。

AbstractInstanceRegistry

如上图,AbstractInstanceRegistry是注册中心的服务注册核心实现类,这里面保存了服务实例的数据,封装了对于服务实例注册、下线、读取等核心方法。

这里讲解一下这个类比较重要的成员变量

服务注册表

private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry= new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();

注册表就是存储的服务实例的信息。Eureka是使用ConcurrentHashMap来进行保存的。键值是服务的名称,值为服务的每个具体的实例id和实例数据的映射,所以也是一个Map数据结构。InstanceInfo就是每个服务实例的数据的封装对象。

服务的上线、下线、读取其实就是从注册表中读写数据。

最近变动的实例队列

private ConcurrentLinkedQueue<RecentlyChangedItem> recentlyChangedQueue = new ConcurrentLinkedQueue<>();

recentlyChangedQueue保存了最近变动的服务实例的信息。如果有服务实例的变动发生,就会将这个服务实例封装到RecentlyChangedItem中,存到recentlyChangedQueue中。

什么叫服务实例发生了变动。举个例子,比如说,有个服务实例来注册了,这个新添加的实例就是变动的实例。

所以服务注册这个操作就会有两步操作,首先会往注册表中添加这个实例的信息,其次会给这个实例标记为新添加的,然后封装到RecentlyChangedItem中,存到recentlyChangedQueue中。

新增

同样的,服务实例状态的修改、删除(服务实例下线)不仅会操作注册表,同样也会进行标记,封装成一个RecentlyChangedItem并添加到recentlyChangedQueue中。

修改

下线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值