看源码方法
看源码首先要了解它的使用,如果不了解它技术的使用、或者特色的话、或者原理的话,你去看源码的话就没什么意义了。 ----Mic
Eureka Server 如何接收请求
通信
接收请求的话,肯定会涉及到通信,一般来说,有http通信,socket通信(NIO、Netty)。
服务端必然会监听请求
Euraka提供了两个类 ApplicationsResource 和 ApplicationResource,这两个类会接收一些请求,类似controller。例如:
基于appId路径的访问
查询服务端所有地址的请求
增量的查询
添加实例
Eureka Cilent 如何注册
spring-clond 服务注册的接口定义和实现
注册的话,得知道spring原理的一些东西,在spring-cloud-commons包下,spring提供了服务注册的接口
spring本身没有对这个接口的实现,这里 EurekaServiceRegistry 实现了这个接口
那么这个实现类什么时候装载到spring容器里的?什么时候被调用的呢?这就涉及到了另一个点。
SmartLifeCycle
先看看关系图
SmartLifeCycle 是干嘛的呢?在spring容器加载完所有Bean并且初始化完成之后,所有实现了 SmartLifeCycle 接口的,都会被触发 start 方法
在spring中它是怎么触发的呢?
我们从sprig cloud启动方法找下去
顺着刷新方法(refresh…)向下找,在 AbstractApplicationContext 中的 refresh() 方法中,有个 finishRefresh() 方法
在finishRefresh() 方法中,我们看到了熟悉的身影
往下再多点两下,会在 DefaultLifecycleProcessor 类中发现我们上面所有说的
start 方法—> spring容器加载完所有Bean并且初始化完成之后会被触发
上图的 lifecycleBeans,就是所有实现了 LifeCycle 的实现类,如果在这里打个调式断点的话,你会发现 lifecycleBeans 里面存放了 EurekaAutoServiceRegistration ,是不是有点眼熟呢? 它和我们前面提到到的 EurekaServiceRegistry,有什么关系呢?
看下 EurekaAutoServiceRegistration 类
原来 EurekaAutoServiceRegistration 持有 EurekaServiceRegistry,通过构造方法注入进来的。
这个两个类关系是有了,下一步就得找到他们是如何装载到spring容器中去的。
了解spring boot自动装配的话,就知道我们应该去找一个像这样命名的配置类—> EurekaXXXAutoXXXConfiguration
最终找到了 EurekaClientAutoConfiguration
在这里,我们看到了熟悉Bean
到这里前前后后好像串起来了。我们理一理,spring启动完成后,会调用 SmartLifeCycle 接口的实现类的 start 方法,而 EurekaAutoServiceRegistration 就是实现了 SmartLifeCycle 接口,所以它有 start 方法,也必然会被调用,同时 EurekaAutoServiceRegistration 还持有 spring-clond 服务注册的接口定义 ServiceRegistry 的实现类 EurekaServiceRegistry,好像猜到了点什么,我们先找到
EurekaAutoServiceRegistration 的 start 方法
果然和我们猜的一样,在 start 方法中会调用 ServiceRegistry 的 register 方法
看下 register 方法
这个注册方法做了两个事:设置状态和健康检测
看看设置状态的方法
到这里,没看到服务注册,发布了一个事件就没了,唯一的线索就是 listeners
找了下,在这里赋值的
再看看 registerStatusChangeListener 方法在哪里被调用了,最终发现 DiscoveryClient 类
DiscoveryClient
DiscoveryClient 在 eureka-client 包下
它持有了 ApplicationInfoManager
前面提到的 listeners 在 initScheduledTasks 方法中被初始化和注册的
此时我们知道了,ApplicationInfoManager 中 被调用的 notify 方法
就在这里
看下 onDemandUpdate 方法
这个方法好像和本地服务的更新有关,我们可能会注意到这句话“Executing on-demand update of local InstanceInfo”,既然是更新,那和注册也有点关系!
再仔细一看,我们会发现一个熟悉的身影
有 run 方法!,难道这个类实现了 Runnable 接口?
果然是这样的, 看看 run 方法
终于发现了注册的字眼了,折腾了这么久,精力没白费,路线是对的!点进去看看,发现又有一个注册方法
再点进的话,发现有3个实现类实现了 register 方法
真相在 AbstractJerseyEurekaHttpClient 中的 register 方法中。
我们看到了 POST字眼,原来是在这里发起的请求通信的,将服务信息封装为 InstanceInfo 对象的数据发送给了服务端。
最后附上Mic老师的图,整个流程更加清晰
原文:https://gper.club/articles/7e7e7f7ff3g59gc0g6f