一、前言
上一讲我们讲到了 Eureka 注册中心的 Server 端有三级缓存来保存注册信息,可以利用缓存的快速读取来提高系统性能。我们再来细看下:
一级缓存:只读缓存 readOnlyCacheMap
,数据结构 ConcurrentHashMap。相当于数据库。
二级缓存:读写缓存 readOnlyCacheMap
,Guava Cache。相当于 Redis 主从架构中主节点,既可以进行读也可以进行写。
三级缓存:本地注册表 registry
,数据结构 ConcurentHashMap。相当于 Redis 主从架构的从节点,只负责读。
看图更清晰,如下图所示:
另外 ConcurrenthashMap 也是一种 map 结构,也就是以键值对的方式进行存储,如下图所示:
Map 结构
二、引发的几个思考
我们再来看下 Eureka 源码,其实不难看懂,下面会做解释。
我们再来看下其中的一种缓存结构:读写缓存。
四、读写缓存
读写缓存,顾名思义,就是既可以进行读,也可以进行写的缓存。读主要是给只读缓存来读取的。写主要是将缓存更新到自己的 Map 中。
下面分别从写缓存的原理、写缓存的源码、过期时机的原理、过期时机的源码几个方面来分别解答。
3.3 实时过期
当有新的服务实例进行注册或者下线、发生故障时,就会把这个对应的服务实例的缓存给过期掉。
如下图所示,最上面的是注册中心,下面三个是服务实例。服务实例发生注册、下线、发生故障,注册中心都是可以感知到的,然后就会主动过期读写缓存对应的服务实例。
(2)服务端,我们也可以考虑关闭从只读缓存读注册表信息,Eureka Client 直接从读写缓存读取。
八、总结
本篇学习了 Eureka 注册中心 Server 端的三层缓存架构,分为 registry、readOnlyCacheMap、readWriteCacheMap,用来保存服务注册信息。
- 默认情况下,每隔 30 秒从读写缓存将注册信息更新到只读缓存。
- 默认情况下,客户端读取注册表时,先从只读缓存读,如果没有,则从读写缓存中读取,如果还是没有,则从本地注册表 registry 读取。
- 默认情况下,每隔 180 秒定时过期读写缓存。
- 服务实例注册、下线、故障时,会实时过期读写缓存。
- 引入了多级缓存,也会带来缓存不一致的问题。