spring cloud:eureka源码之我见(二)基于Eureka server的启动源码剖析

eureka server的启动相当于是注册中心的启动,而eureka client的启动相当于是服务的启动。eureka server的启动是依赖于eureka client的启动的,因为eureka server本质上也是一个eureka client。在eureka server使用集群模式部署的时候,eureka server会将自己作为一个eureka client向其他的eureka server去注册。

eureka server本质就是一个web应用,而web应用最核心的就是web.xml。我们可以在web.xml中看到他有个listenerlistener是在web应用启动的时候就会执行的,负责对这个web应用进行初始化,比如启动一些后台线程,加载配置文件等。

而EurekaBootStrap就是负责eureka server的初始化的。该监听器位于eureka-core包中,它执行初始化的方法是contextInitialized(),这个方法就是整个eureka-server启动初始化的一个入口。

1.initEurekaEnvironment(),顾名思义,就是初始化eureka-server的环境。这里会调用ConfigurationManager.getConfigInstance()方法,初始化ConfigurationManager的实例。ConfigurationManager其实就是配置管理器,管理eureka所有的配置,读取配置文件里的配置到内存里,供后续的eureka-server使用。

这里ConfigurationManager使用的是单例模式,double check+volatile实现的线程安全的单例模式。

ConfigurationManager创建了一个ConcurrentCompositeConfiguration实例,这个实例包含了eureka所有的配置,然后将其作为单例返回。

之后,初始化数据中心的配置,如果没有配置的话,就是DEFAULT data center。初始化eurueka运行的环境,如果你没有配置的话,默认就给你设置为test环境。

环境初始化结束。

2.initEurekaServerContext()

(1)该方法第一步是加载eureka-server.properties中的配置。

Eureka提供了一个EurekaServerConfig接口,里面有一堆的getXXX()方法,包含了eureka server需要使用的所有的配置,这些配置项都是通过接口的get方法获取的。

而DefaultEurekaServerConfig是这个接口的实现类,创建实例的时候,会执行一个init方法,在这个方法中,就会完成对eureka-server.properties文件中配置项的加载。EUREKA_PROPS_FILE,对应着要加载的eureka的配置文件的名字(默认为eureka-server)。

eureka-server 和.properties拼接起来,组成了配置文件名。将eureka-server.properties中的配置,加载到Properties对象中去,然后加载eureka-server-环境.properties中的配置,加载到另一个Properties中,覆盖之前老的Properties。

将加载出来的Properties的配置项都放到ConfigurationManager上,交由他管理。

在DefaultEurekaServerConfig类中各种配置项获取的方法中,配置项的名字是硬编码的,是从DynamicPropertyFactory里获取的(DynamicPropertyFactory来源于ConfigurationManager,所以,ConfigurationManager加载的配置项可通过DynamicPropertyFactory获取)。在从DynamicPropertyFactory中获取配置项时,如果没配置,则会使用默认值。

(2)第二步是初始化eureka-server内部的eureka-client,用来跟其他eureka-server节点注册和通信。

Application在eureka中是个什么概念?如果你是一个eureka client,客户端,扮演的角色其实是一个服务,你作为一个服务会向eureka server去注册。Application,其实你可以认为,就是一个eureka client -> Application,服务。

第二步中一开始就是创建EurekaInstanceConfig接口的子类实例,该接口的功能与EurekaServerConfig基本相同。将eureka-client.properties文件中的配置加载到ConfigurationManager中,基于EurekaInstanceConfig对外暴露的方法来获取配置项的值,并且一样有默认值。

InstanceInfo,存储的是这个服务实例本身的信息,直接用了构造器模式,用Instance.Builder来构造一个复杂的代表一个服务实例的InstanceInfo对象。核心的思路是,从之前获取的EurekaInstanceConfig中读取服务实例的配置信息,再构造几个其他对象,构建InstanceInfo。

基于EurekaInstanceConfig与InstanceInfo,构造一个ApplicationInfoManager,后面会基于ApplicationInfoManager对服务实例进行管理。

EurekaClientConfig,也是接口,也是对外暴露了一堆配置项,只不过与EurekaInstanceConfig不同的是,EurekaClientConfig关联的是Eureka-client的配置,而EurekaInstanceConfig代表了服务实例的一些配置项。

EurekaInstanceConfig,重在应用实例,例如,应用名、应用的端口等等。此处应用指的是,Application Consumer 和 Application Provider。
EurekaClientConfig,重在 Eureka-Client,例如, 连接的 Eureka-Server 的地址、获取服务提供者列表的频率、注册自身为服务提供者的频率等等。

此时,基于ApplicationInfoManager与EurekaClientConfig,构建了EurekaClient,这里,使用的是他的子类DiscoveryClient进行实例化。

DiscoveryClient实例化的流程如下:

a.读取eurekaClientConfig包括EurekaTransportConfig

b.保存EurekaInstanceConfig与InstanceInfo

c.处理了是否要注册以及抓取注册表,如果不要的话,释放一些资源

d.支持调度的线程池

e.支持心跳的线程池

f.支持缓存刷新的线程池

g.EurekaTransport,支持底层的eureka client和eureka server通信的组件,对网络通信组件进行了一些初始化操作

h.如果配置了需要抓取注册表,那就抓取,如果没有,那就不抓取

i.初始化调度任务,如果要抓取注册表的话,就会注册一个定时任务,按照设定的时间间隔,每隔一定时间(默认为30s),去执行一个cacheRefreshThread,放入调度线程池中。

如果要向eureka server注册的话,设置一个定时任务,每隔一定时间发送心跳,执行一个HeartBeatThread;

创建副本实例传播器(InstanceInfoReplicator),将自己作为定时任务调度。

创建服务实例状态变更监听器,如果配置了监听,那么就会注册监听器。

(3)第三步,构造PeerAwareInstanceRegistry。可以感知eureka server集群的服务实例注册表,即eureka client(作为服务实例)过来注册的的注册表,而且这个注册表是可以感知到eureka server集群的。假如有一个eureka server集群的话,那么这里就包含了其他的eureka server中的服务实例注册表的信息。

(4)第四步,构造PeerEurekaNodes,这个就代表了eureka server集群。

(5)第五步,构造了EurekaServerContext,基于以上构造的对象完成EurekaServerContext的初始化,该类代表了eureka server的一个服务器上下文,包含了服务器需要的所有的东西。之后,将其放在一个holder中,在整个系统运行期间,不管是谁,想要获取EurekaServerContext,都可以从这个holder中获取。

(6)第六步,EurekaServerContext.initialize()

peerEurekaNodes.start();

这里,就是将eureka server集群启动起来,更新一下eureka server的信息,让当前的eureka server感知到其他的eureka server。然后启动了一个定时调度任务,后台线程,每隔一定时间,更新eureka server集群的信息。

registry.init(peerEurekaNodes);

基于eureka server集群的信息,来初始化注册表。将eureka server集群中所有的eureka server的注册表的信息,都抓取过来,放到自己本地的注册表中去。

(7)第七步,registry.syncUp()

从相邻的一个eureka server节点拷贝注册表的信息,如果拷贝失败,就等待30s找下一个(重试5次)

(8)第八步,EurekaMonitors.registerAllStats();

跟eureka自身的监控机制相关联。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值