当前位置:网站首页>8 张图 | 剖析 Eureka 的首次同步注册表
8 张图 | 剖析 Eureka 的首次同步注册表
2022-06-28 07:21:00 【不会写代码的女程序猿】
注册表对于注册中心尤为重要,所有的功能都是围绕这个注册表展开。比如服务 A 要想访问服务 B,就得知道服务 B 的 IP 地址和端口号吧。如下图所示,传统的方式就是服务 A 知道了服务 B 的地址后,发送 HTTP 请求到对应的 API 地址上。

那服务 A 和 服务 B 的信息其实就是放在注册中心的注册表里面的,由注册中心统一管理所有服务的注册、下线。服务 A 和 服务 B 想要获取注册信息,统一访问注册中心,拿到注册表,就知道其他服务的 IP 地址 和端口号了。

上一讲,我们讲到一个 Eureka Client 成功注册到 Eureka Server 后,Eureka Server 就会把注册表信息存到一个 ConcurrentHashMap 中。
那 Client 怎么获取其他客户注册信息呢?

二、首次获取注册信息
首先我们想一下,服务 B 发送注册请求到注册中心了,那服务 A 就得获取注册表了吧,服务 A 本地一开始肯定是没有注册表信息的,那肯定就得到注册中心把注册表全部拉取一遍了。(这里服务 A 也称作 Eureka 客户端)
服务 A 对于注册中心来说,就是
初次见面,服务 A 想把所有注册信息都在自己本地存一份,方便后续的 API 调用。
接下来我们从源码角度分析下客户端怎么获取全量注册表的吧。
客户端发送获取的请求
Client 初始化的时候,就会从 Eureka 注册中心获取全量的注册表:

首次获取注册信息就是用在 DiscoveryClient 初始化的时候获取的。我们可以从源码中找到如下判断:
if (clientConfig.shouldFetchRegistry() && !fetchRegistry(false)) {
fetchRegistryFromBackup();
}
这段代码的意思如图所示:

就是先根据是否配置了 shouldFetchRegistry,如果配置了,则会调用 fetchRegistry 方法获取注册表。
因为是新的 client,所以肯定是没有注册信息的,所以本地的变量 applications = null。然后根据几个条件来判断是否需要全量获取注册表,满足其中一个条件就会全量获取:

- 条件一:是否强制全量获取。传的 false,不需要全量。
- 条件二:注册表信息是否为空。application == null,为空,需要全量获取。
- 条件三:获取已注册的 client 的个数是否等于 0。是的,需要全量获取。
因为满足 applications=null,所以需要全量获取。
获取全量注册信息的方法:
getAndStoreFullRegistry()
在这个里面就会发送下面这个 HTTP 请求调用 jersey 的 restful 接口:
getApplications()
然后 Eureka Server 处理这个 http 的请求的类是在这里:ApplicationsResource 类的 getContainers 方法。这个方法里面就会去拿 Server 那边注册表了。
三、Server 端的注册表缓存
Server 端会把注册表放到缓存里面,读取注册表其实是从缓存里面读取出来的。
分为两级缓存,只读缓存 readOnlyCacheMap 和读写缓存 readOnlyCacheMap。
如下图所示:

缓存的读取逻辑如下:
Jersey Servlet 处理 HTTP 请求。
首先默认会先从只读缓存里面找。
没有的话,再从读写缓存里面找。
找到了的话就更新只读缓存,并返回找到的缓存。
还找不到的话,就返回空。

留几个问题,放到缓存架构那篇再讲:
(1)两级缓存数据怎么来的?
(2)缓存数据如何更新的?
(3)缓存如何过期?
然后,Eureka Client 获取注册表信息后,就会存到本地 localRegionApps 变量中。这样 Client 就会有一份 Server 的注册表信息了。
localRegionApps.set(this.filterAndShuffle(apps));
四、总结
注册表无论是对于 Client 还是 Server 来说,都非常重要:
- 对于 Server 端来说,为了更好的提供查询注册表的服务,使用了多级缓存来缓存注册表信息。
- 对于 Client 端来说,首次获取注册表时就会全量抓取注册表,存在自己本地。
边栏推荐
- 卸载重装最新版mysql数据库亲测有效
- My MVVM open source project "travel epidemic prevention app" has been released
- 推荐几款0代码、免费、现学现用的可视化工具
- R 语言 Hitters 数据分析
- Optimization steps of SQL statements (II) -- MySQL statement optimization
- Face to face experience --- test engineer web side automation --- interview questions for large factories
- MySQL installation steps - how to create a virtual machine under Linux (1)
- mysql57 zip文件安装
- R 语言 ggmap 可视化集群
- DOM parsing of XML file case code sentence by sentence analysis
猜你喜欢

Pytorch RNN learning notes

LeetCode+ 51 - 55 回溯、动态规划专题

The practice of event driven architecture in vivo content platform

PLC -- 笔记
![[C#][转载]furion框架地址和教程地址](/img/b2/e1c30153c4237188b60e9523b0a5d8.png)
[C#][转载]furion框架地址和教程地址

My MVVM open source project "travel epidemic prevention app" has been released

以动态规划的方式求解最长回文子串

C language tutorial

A gadget can write crawlers faster

C语言教程大全
随机推荐
[rust translation] implement rust asynchronous actuator from scratch
全方位透析真实企业软件测试流程
okcc呼叫中心没有电脑的坐席能不能开展工作?
看似简单的光耦电路,实际使用中应该注意些什么?
[rust daily] May 24, 2020 rush, rocket, Mun, caspin
In idea, the get and set methods may be popular because the Lombok plug-in is not installed
什么是一致性哈希?可以应用在哪些场景?
同花顺网上开户安全吗
MySQL master-slave replication, detailed configuration, create unable to connect processing prompt
Pfizer's new Guankou medicine has entered the Chinese market, and the listing of relevant products of domestic pharmaceutical enterprises is just around the corner
Sword finger offer II 091 Paint the house
[ thanos源码分析系列 ]thanos query组件源码简析
Rust FFI programming - libc crate
DBeaver 22.1.1 发布,可视化数据库管理平台
面经---测试工程师web端自动化---大厂面试题
ABAP skill tree
[rust daily] published on rust 1.43.0 on April 23, 2020
MySQL installation steps - installing MySQL on Linux (3)
What should I do if the version is incompatible with the jar package conflict?
The practice of event driven architecture in vivo content platform