这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战
首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca…
一 . 前言
文章目的
- 梳理 Eureka 服务注册的流程
- 深入 服务注册的源码
对应配置类
Eureka Client 的配置是通过 EurekaClientAutoConfiguration 和 EurekaDiscoveryClientConfiguration 进行处理的
1 | java复制代码C- EurekaDiscoveryClientConfiguration |
二 . 服务的注册
来看一下 Eureka 是如何注册服务的 , Eureka 通过 @EnableDiscoveryClient 开启服务的注册
Eureka 的服务注册的主要线路为 Lifecycle 发起 EurekaServiceRegistry 的生命周期控制
服务注册核心的类为 : EurekaServiceRegistry , 这个类提供了以下几个方法
1 | jAVA复制代码C- EurekaServiceRegistry |
2.1 Eureka 注册的起点
1 | java复制代码// C- EurekaServiceRegistry |
补充 : start 的入口
1 | java复制代码// Start 方法基于 Lifecycle 接口 , 这个接口用于控制Bean 的生命周期 ,当 Application 发生 开启和停止时 , 都会调用对应的钩子事件 |
2.1.1 注册服务
Step 1 : register 注册的起点
1 | java复制代码// C- EurekaServiceRegistry |
Step 2 : 修改状态 , 调用监听器
1 | java复制代码C- EurekaServiceRegistry |
Step 3 : 发起发更新逻辑 , 对远程服务器进行更新
1 | java复制代码C- InstanceInfoReplicator |
补充 : InstanceInfoReplicator 的作用
- 配置了单个更新线程,以保证对远程服务器的连续更新
- 更新任务可以通过onDemandUpdate() 按需调度
- 任务处理速率受突发大小限制
- 一个新的更新任务总是自动调度在一个较早的更新任务之后。
- 但如果启动了按需更新任务,则定时的自动更新任务将被丢弃(新的按需更新任务将在新的按需更新任务之后调度新的任务)
Step 4 : 调用 InstanceInfoReplicator # run
1 | java复制代码public void run() { |
2.2 注册服务
此处就开始通过 DiscoveryClient 进行注册逻辑 :
1 | java复制代码C- DiscoveryClient |
2.3 register 循环调用
1 | JAVA复制代码// 这里和下方的模式非常相似 ,都是传个匿名函数进去 , 再由里面发起回调 |
细节点 : 轮询调用
// 此处进行了一个链式调用 ,分别调用了
- C- SessionedEurekaHttpClient : 强制在一个定期的间隔(一个会话)重新连接,防止客户端永远坚持一个特定的Eureka服务器实例
- C- RetryableEurekaHttpClient : 在集群中的后续服务器上重试失败的请求
- C- RedirectingEurekaHttpClient : 该Client 会进行 Server 重定向 , 并且针对最终解析的端点执行请求
- C- MetricsCollectingEurekaHttpClient : 收集和统计JerseyApplicationClient发送请求和响应的行为信息
1 | java复制代码// 通常内部是通过 clientFactory 构建下一个 HttpClient , 这个对象在 EurekaHttpClients 中通过构造器传入 |
补充 : 调用的目的 , 为什么这里要循环几个 HttpClient ?
查看这几个 HttpClient ,感觉他们应该更像是 Filter ,只不过他们的职能是发起请求 ,而结构类似于 Filter 过滤链
关于这一块可以单章看一下 , 这里只关注最后的一个 , 也就是 MetricsCollectingEurekaHttpClient
2.4 核心 HttpClient
1 | java复制代码C- MetricsCollectingEurekaHttpClient |
补充 : JerseyApplicationClient 的创建
1 | java复制代码// Step 1 : JerseyEurekaHttpClientFactory 的创建 |
2.5 发起 Server 请求流程
1 | java复制代码// C- AbstractJerseyEurekaHttpClient |
这里就会调用 Server 端 ApplicationResource , 具体流程后面说 Server 端时看看
三 . 补充
3.1 HttpClient 的结构设计
HttpClient 的这种调用模式是一种典型的 .. 设计模式 , 其中大量使用了 AtomicReference 原之类的特性 ,
3.2 为什么 Eureka 里面大量使用了原子类 ?
首先 : 原子类主要通过 CAS (compare and swap) + volatile 和 native 方法来保证原子操作
前文中看到使用了 ScheduledExecutorService 发起了注册 , 实际debug 中发现这个里面实际上存在很多多线程调用 .
总结
之前看比较新的框架 , 往往可以看到很多 Spring 的影子 , 很多都会选择用 Spring 作为管理 .
但是看了Eureka 的框架才意识到 , 其实很多框架是没有和 Spring 集成的 , Spring 很好用 ,但是Eureka 如果用了 , 返回会显得很臃肿
eureke 中的技术栈有一定年限了, 但是不意味着不好用了 , 这一套模式前几年我还用过 , 现在看起来 , 颇有感触
本文转载自: 掘金