02.SpringCloudEurekaServer原理-SpringCloudEurekeServer原理分析
2023-06-14 20:12:21 0 举报
AI智能生成
Spring Cloud Eureka Server 原理
作者其他创作
大纲/内容
ApplicationResource<br>处理客户端请求
addInstance()<br>处理注册请求
register()<br>注册服务
super.register()<br>先调用父类的方法完成服务注册
先校验注册表中是否已经有此服务<br>一般都没有,特殊情况才会有
updateRenewsPerMinThreshold()<br>如果注册表中没有表示新注册服务,这里会计算自我保护阈值
如果注册请求的 overriddenStatus 状态不为 UNKNOWN && overriddenInstanceStatusMap 缓存中不包含<br>就添加到 overriddenInstanceStatusMap 缓存中<br>
从 overriddenInstanceStatusMap 缓存中获取状态<br>给注册请求的 registrant 设置 overriddenStatus<br>
getOverriddenInstanceStatus()<br>给注册请求的 registrant 设置计算出来的 status<br>
getInstanceInfoOverrideRule()<br>获取状态计算规则器
rule.apply()<br>这里是一个执行器链,挨个调用 apply() 方法校验<br>
FirstMatchWinsCompositeRule<br>循环所有拦截器链,匹配上就直接返回状态
DownOrStartingRule<br>如果实例 status 状态是 DOWN 或者 STARTING 就直接返回
OverrideExistsRule<br>如果 overriddenInstanceStatusMap 缓存中有状态,就直接返回
LeaseExistsRule<br>从注册表中如果能够获取到实例 && 实例状态如果是 UP 或者 OUT_OF_SERVICE,就返回<br>
AlwaysMatchInstanceStatusRule<br>直接使用客户端的状态返回
将本次修改记录到 recentlyChangedQueue 队列中
replicateToPeers()<br>向集群中的其他节点发送数据同步请求<br>事件类型是【Action.Register】
InstanceResource<br>处理客户端请求
statusUpdate()<br>处理状态变更请求
statusUpdate()<br>更改状态
super.statusUpdate()<br>先调用父类的方法完成状态变更
将新的状态保存到 overriddenInstanceStatusMap 缓存中
修改注册表中 InstanceInfo 的 overriddenStatus 信息
修改注册表中 InstanceInfo 的 status 信息
将本次修改记录到 recentlyChangedQueue 队列中
replicateToPeers()<br>向集群中的其他节点发送数据同步请求<br>事件类型是【Action.StatusUpdate】
先判断是否是一个同步请求,如果是直接 return<br>防止递归死循环
replicateInstanceActionsToPeers()<br>获取集群中的所有其它节点,挨个同步(需要排除自己)<br>防止递归死循环
deleteStatusUpdate()<br>处理删除状态请求
deleteStatusOverride()<br>删除状态
super.deleteStatusOverride()<br>先调用父类的方法完成状态删除<br>
从 overriddenInstanceStatusMap 缓存中删除状态
修改注册表中 InstanceInfo 的 overriddenStatus 信息为 UNKNOWN 状态
修改注册表中 InstanceInfo 的 status 信息
将本次修改记录到 recentlyChangedQueue 队列中
replicateToPeers()<br>向集群中的其他节点发送数据同步请求<br>事件类型是【Action.DeleteStatusOverride】
renewLease()<br>处理续约请求
renew()<br>先续约
super.renew()<br>先调用父类的方法完成续约<br>
getOverriddenInstanceStatus()<br>计算该请求的 InstanceStatus 状态
如果续约的状态和上一步计算出来的状态不一致<br>就把 status 状态改成上面计算出来的状态<br><font color="#f44336">【即不相信 client 提交过来的状态,这个状态需要经过计算】</font>
replicateToPeers()<br>向集群中的其他节点发送数据同步请求<br>事件类型是【Action.Heartbeat】
validateDirtyTimestamp()<br>根据客户端传入的 lastDirtyTimestamp 计算<br>这里只用考虑集群之间的 Replication 请求
如果客户端的传入的 lastDirtyTimestamp > 服务端缓存的 lastDirtyTimestamp<br>返回 NOT_FOUND 状态<br>这种情况是正常现象,需要同步,因为别人的时间更新
如果客户端的传入的 lastDirtyTimestamp < 服务端缓存的 lastDirtyTimestamp && 是 Replication 请求<br>返回 CONFLICT 状态<br>这种情况是冲突的,不需要同步,因为我自己的时间别别人的时间还要新
其余情况返回 OK 状态
storeOverriddenStatusIfRequired()<br>如果是 NOT_FOUND 状态 && 是 Replication 请求
修改缓存 overriddenInstanceStatusMap 中的状态
修改注册表中 InstanceInfo 的 status 信息
cancelLease()<br>处理服务关闭请求
cancel()<br>关闭服务
super.cancel()<br>先调用父类的方法完成服务删除<br>
internalCancel()<br>服务删除
从注册表中删除该实例
从 overriddenInstanceStatusMap 缓存中删除
将本次修改记录到 recentlyChangedQueue 队列中
清除相关缓存
updateRenewsPerMinThreshold()<br>因为有服务下线,这里需要更新自我保护机制算法
replicateToPeers()<br>向集群中的其他节点发送数据同步请求<br>事件类型是【Action.Cancel】
deleteStatusUpdate()<br>处理客户端的【CANCEL_OVERRIDE】覆盖状态删除请求<br>
super.deleteStatusOverride()<br>先调用父类的方法完成覆盖状态删除<br>注意这里并不会删除缓存
从 overriddenInstanceStatusMap 缓存中删除
将 overriddenStatus 状态设置为 UNKNOWN
将 status 状态设置为 UNKNOWN
将本次修改记录到 recentlyChangedQueue 队列中
清除相关缓存
replicateToPeers()<br>向集群中的其他节点发送数据同步请求<br>事件类型是【Action.DeleteStatusOverride】
ApplicationsResource<br>处理客户端请求
getContainers()<br>处理客户端获取全部应用信息请求
构建缓存 key(ALL_APPS)
responseCache.get(cacheKey)<br>从缓存中获取
getContainerDifferential()<br>处理客户端获取增量应用信息请求<br>
构建缓存 key(ALL_APPS_DELTA)<br>
responseCache.get(cacheKey)<br>从缓存中获取
ResponseCacheImpl<br>缓存实现类
generatePayload()<br>根据缓存 key 获取结果
getApplicationsFromMultipleRegions()<br>获取全量数据
直接从 registry 中获取所有数据<br>封装成 InstanceInfo 返回
getApplicationDeltasFromMultipleRegions()<br>获取增量数据
从 recentlyChangedQueue 队列中遍历所有数据<br>封装成 InstanceInfo 返回 <br>当然这个队列也会定时清除
EurekaServerAutoConfiguration<br>Spring Boot 提供的 SPI
EurekaServerInitializerConfiguration<br>向容器中导入组件
start()<br>它实现了 SmartLifecycle 接口<br>所以在启动时会回调这个方法
contextInitialized()<br>执行初始化方法
initEurekaServerContext()<br>执行初始化方法
registry.openForTraffic()<br>开启清理任务
super.postInit()<br>调用父类的清理方法
evictionTimer.schedule()<br>开启定时清理任务
EvictionTask.run()<br>具体的清理任务
getCompensationTimeMs()<br>计算补偿时间
evict(compensationTimeMs)<br>清理过期的实例
isLeaseExpirationEnabled()<br>先判断是否触发了自我保护机制<br>如果触发了就直接跳过清理
如果禁用了自我保护机制,直接返回<br>
getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold<br>如果每分钟收到的续约数 > 自我保护机制的阈值,就表示没触发
lease.isExpired(additionalLeaseMs)<br>从注册表中查找已经过期的实例<br>
internalCancel()<br>使用 Random 清除最小过期的实例数,不是全部清除<br>
0 条评论
下一页