Eureka 源码解析 —— 应用实例注册发现(一)之注册
来源:互联网 发布:南风知我意 吹梦到西洲 编辑:程序博客网 时间:2024/06/05 11:04
摘要: 原创出处 http://www.iocoder.cn/Eureka/instance-registry-register/ 「芋道源码」欢迎转载,保留摘要,谢谢!
本文主要基于 Eureka 1.8.X 版本
- 1. 概述
- 2. Eureka-Client 发起注册
- 2.1 应用实例信息复制器
- 2.2 刷新应用实例信息
- 2.3 发起注册应用实例
- 3. Eureka-Server 接收注册
- 3.1 接收注册请求
- 3.2 Lease
- 3.3 注册应用实例信息
- 蓝框部分,为本文重点。
- 非蓝框部分,Eureka-Server 集群间复制注册的应用实例信息,不在本文内容范畴。
- 请支持正版。下载盗版,等于主动编写低级 BUG 。
- 程序猿DD —— 《Spring Cloud微服务实战》
- 周立 —— 《Spring Cloud与Docker微服务架构实战》
- 两书齐买,京东包邮。
- 配置
eureka.registration.enabled = true
,Eureka-Client 向 Eureka-Server 发起注册应用实例的开关。 - InstanceInfo 在 Eureka-Client 和 Eureka-Server 数据不一致。
com.netflix.discovery.InstanceInfoReplicator
,应用实例信息复制器。调用
InstanceInfoReplicator#start(...)
方法,开启应用实例信息复制器。实现代码如下:- 执行
instanceInfo.setIsDirty()
代码块,因为 InstanceInfo 刚被创建时,在 Eureka-Server 不存在,也会被注册。 - 调用
ScheduledExecutorService#schedule(...)
方法,延迟initialDelayMs
毫秒执行一次任务。为什么此处设置scheduledPeriodicRef
?在InstanceInfoReplicator#onDemandUpdate()
方法会看到具体用途。
- 执行
定时检查 InstanceInfo 的状态(
status
) 属性是否发生变化。若是,发起注册。实现代码如下:
- 调用
DiscoveryClient#refreshInstanceInfo()
方法,刷新应用实例信息。此处可能导致应用实例信息数据不一致,在「2.2」刷新应用实例信息 详细解析。 - 调用
DiscoveryClient#register()
方法,Eureka-Client 向 Eureka-Server 注册应用实例。 - 调用
ScheduledExecutorService#schedule(...)
方法,再次延迟执行任务,并设置scheduledPeriodicRef
。通过这样的方式,不断循环定时执行任务。
- 调用
com.netflix.appinfo.ApplicationInfoManager.StatusChangeListener
内部类,监听应用实例信息状态的变更。调用
ApplicationInfoManager#registerStatusChangeListener(...)
方法,注册应用实例状态变更监听器。实现代码如下:业务里,调用
ApplicationInfoManager#setInstanceStatus(...)
方法,设置应用实例信息的状态,从而通知InstanceInfoReplicator#onDemandUpdate()
方法的调用。实现代码如下:InstanceInfoReplicator#onDemandUpdate()
,实现代码如下:- 调用
Future#cancel(false)
方法,取消定时任务,避免无用的注册。 - 调用
InstanceInfoReplicator#run()
方法,发起注册。
- 调用
调用
ApplicationInfoManager#refreshDataCenterInfoIfRequired()
方法,刷新数据中心相关信息,实现代码如下:- 关注应用实例信息的
hostName
、ipAddr
、dataCenterInfo
属性的变化。 - 一般情况下,我们使用的是非 RefreshableInstanceConfig 实现的配置类( 一般是 MyDataCenterInstanceConfig ),因为
AbstractInstanceConfig.hostInfo
是静态属性,即使本机修改了 IP 等信息,Eureka-Client 进程也不会感知到。TODO[0022]:看下springcloud 的实现
- 关注应用实例信息的
调用
ApplicationInfoManager#refreshLeaseInfoIfRequired()
方法,刷新租约相关信息,实现代码如下:
- 关注应用实例信息的
renewalIntervalInSecs
、durationInSecs
属性的变化。
- 关注应用实例信息的
调用
HealthCheckHandler#getStatus()
方法,健康检查。这里先暂时跳过,我们在TODO[0004]:健康检查 详细解析。- 调用
AbstractJerseyEurekaHttpClient#register(...)
方法,POST
请求 Eureka-Server 的apps/${APP_NAME}
接口,参数为 InstanceInfo ,实现注册实例信息的注册。 - 请求头
isReplication
参数,和 Eureka-Server 集群复制相关,暂时跳过。 调用
PeerAwareInstanceRegistryImpl#register(...)
方法,注册应用实例信息。实现代码如下:- 调用父类
AbstractInstanceRegistry#register(...)
方法,注册应用实例信息。
- 调用父类
holder
属性,租约的持有者。在 Eureka-Server 里,暂时只有 InstanceInfo 使用。registrationTimestamp
属性,注册( 创建 )租约时间戳。在构造方法里可以看租约对象的创建时间戳即为注册租约时间戳。serviceUpTimestamp
属性,开始服务时间戳。注册应用实例信息会使用到它如下两个方法,实现代码如下:lastUpdatedTimestamp
属性,最后更新租约时间戳。每次续租时,更新该时间戳。注册应用实例信息会使用到它如下方法,实现代码如下:duration
属性,租约持续时间,单位:毫秒。当租约过久未续租,即当前时间 -lastUpdatedTimestamp
>duration
时,租约过期。evictionTimestamp
属性,租约过期时间戳。- 第 3 行 :添加到应用实例覆盖状态映射,在 《Eureka 源码解析 —— Eureka-Server 集群同步》 详细解析。
- 第 6 至 7 行 :增加注册次数到监控。配合 Netflix Servo 实现监控信息采集。
第 5 至 16 行 :获得应用实例信息对应的租约。
registry
实现代码如下:第 17 至 30 行 :当租约已存在,判断 Server 已存在的 InstanceInfo 的
lastDirtyTimestamp
是否大于( 不包括等于 ) Client 请求的 InstanceInfo ,若是,使用 Server 的 InstanceInfo 进行替代。- 第 31 至 44 行 :增加
numberOfRenewsPerMinThreshold
、expectedNumberOfRenewsPerMin
,自我保护机制相关,在 《Eureka 源码解析 —— 应用实例注册发现(四)之自我保护机制》 有详细解析。 - 第 45 至 52 行 :创建租约,并添加到租约映射(
registry
)。 第 53 至 58 行 :添加到最近注册的调试队列(
recentRegisteredQueue
),用于 Eureka-Server 运维界面的显示,无实际业务逻辑使用。实现代码如下:第 59 至 68 行 :添加到应用实例覆盖状态映射,在 《Eureka 源码解析 —— Eureka-Server 集群同步》 详细解析。
- 第 69 至 73 行 :设置应用实例的覆盖状态(
overridestatus
),避免注册应用实例后,丢失覆盖状态。在《应用实例注册发现 (八)之覆盖状态》详细解析。 - 第 75 至 78 行 : 获得应用实例最终状态,并设置应用实例的状态。在《应用实例注册发现 (八)之覆盖状态》详细解析。
- 第 80 至 84 行 :设置租约的开始服务的时间戳( 只有第一次有效 )。
第 85 至 88 行 :设置应用实例信息的操作类型为添加,并添加到最近租约变更记录队列(
recentlyChangedQueue
)。recentlyChangedQueue
用于注册信息的增量获取,在《应用实例注册发现 (七)之增量获取》详细解析。实现代码如下:第 89 至 90 行 :设置租约的最后更新时间戳。
- 第 91 至 92 行 :设置响应缓存( ResponseCache )过期,在《Eureka 源码解析 —— 应用实例注册发现 (六)之全量获取》详细解析。
- 第 96 至 97 行 :释放锁。
1. 概述
本文主要分享 Eureka-Client 向 Eureka-Server 注册应用实例的过程。
FROM 《深度剖析服务发现组件Netflix Eureka》 二次编辑
推荐 Spring Cloud 书籍:
2. Eureka-Client 发起注册
Eureka-Client 向 Eureka-Server 发起注册应用实例需要符合如下条件:
每次 InstanceInfo 发生属性变化时,标记 isInstanceInfoDirty
属性为 true
,表示 InstanceInfo 在 Eureka-Client 和 Eureka-Server 数据不一致,需要注册。另外,InstanceInfo 刚被创建时,在 Eureka-Server 不存在,也会被注册。
当符合条件时,InstanceInfo 不会立即向 Eureka-Server 注册,而是后台线程定时注册。
当 InstanceInfo 的状态( status
) 属性发生变化时,并且配置 eureka.shouldOnDemandUpdateStatusChange = true
时,立即向 Eureka-Server 注册。因为状态属性非常重要,一般情况下建议开启,当然默认情况也是开启的。
Let’s Go。让我们看看代码的实现。
2.1 应用实例信息复制器
2.2 刷新应用实例信息
调用 DiscoveryClient#refreshInstanceInfo()
方法,刷新应用实例信息。此处可能导致应用实例信息数据不一致,实现代码如下:
2.3 发起注册应用实例
调用 DiscoveryClient#register()
方法,Eureka-Client 向 Eureka-Server 注册应用实例,实现代码如下:
3. Eureka-Server 接收注册
3.1 接收注册请求
com.netflix.eureka.resources.ApplicationResource
,处理单个应用的请求操作的 Resource ( Controller )。
注册应用实例信息的请求,映射 ApplicationResource#addInstance()
方法,实现代码如下:
3.2 Lease
在看具体的注册应用实例信息的逻辑之前,我们先来看下 com.netflix.eureka.lease.Lease
,租约。实现代码如下:
3.3 注册应用实例信息
调用 AbstractInstanceRegistry#register(...)
方法,注册应用实例信息,实现代码如下:
- Eureka 源码解析 —— 应用实例注册发现(一)之注册
- Eureka 源码解析 —— 应用实例注册发现(二)之续租
- Eureka 源码解析 —— 应用实例注册发现(三)之下线
- Eureka 源码解析 —— 应用实例注册发现(四)之自我保护机制
- Eureka 源码解析 —— 应用实例注册发现(五)之过期
- Eureka 源码解析 —— 应用实例注册发现(六)之全量获取
- Eureka 源码解析 —— 应用实例注册发现(七)之增量获取
- Eureka 源码解析 —— 应用实例注册发现(八)之覆盖状态
- Eureka 源码解析 —— Eureka源码解析 —— 应用实例注册发现 (九)之岁月是把萌萌的读写锁
- Spring-cloud & Netflix 源码解析:Eureka 服务注册发现接口 ****
- Spring Cloud Eureka 服务注册与发现中心(一)
- SpringCloud教程一:服务注册与发现(Eureka)
- spring could 之服务的注册与发现(Eureka)
- SpringCloud——Eureka服务注册和发现
- SpringCloud——Eureka服务注册和发现
- Eureka 源码解析 —— Eureka-Client 初始化(一)之 EurekaInstanceConfig
- Eureka 源码解析 —— Eureka-Server 启动(一)之 ServerConfig
- Eureka-服务注册于发现
- linux centOS 安装apache+php+mysql及安装discuz
- Espresso检测不到Intent,Recorded intents:[]
- 导入新的maven项目时,目录结构变化,而且build path显示不正常。
- 各种开关的教程---凯利讯半导体
- 译文 | 与TensorFlow的第一次接触 第三章:聚类
- Eureka 源码解析 —— 应用实例注册发现(一)之注册
- 软件工程师的职业建议
- gpg 加密工具的使用
- 安装vue-cli脚手架提示Error: spawn npm ENOENT的解决方式
- 临时
- Android城市索引含定位和热门城市(悬浮块+右侧字母索引)
- 栈的理解 IAR/MDK修改stack/heap
- 3d_coordinates 测量世界坐标中的倾斜物体
- pthread