eureka server启动流程
spring cloud采用SPI自动装配,这个文件下面有一个类EurekaServerAutoConfiguration,这个就是eureka核心启动类。

我们点进去看这个类

这个类,有一些注解,我们一个一个来分析一下
1.@Configuration
表明这个类是一个配置类,配置spring容器,通常这种类里面都有一个或多个@Bean注解,用于被扫描到初始到容器里。
2.@Import({EurekaServerInitializerConfiguration.class})
导入一个配置类,导入的配置类是EurekaServerInitializerConfiguration这个类,这个类是在Spring容器初始化完成之后做一些事情,它内部的start方法,会初始化 EurekaServerContext的细节,发布eureka注册表启动事件,给状态设置属性,标明正在运行。
3.@ConditionalOnBean({Marker.class})
标明,想要构建这一个配置类,必须有Marker,而这个Marker对象是什么呢,其实这个Marker是有另一个注解决定的,我们在eureka工程的Application运行的类上通常都加一个EnableEurekaServer注解,标明这个是个eureka的server端,而在这个注解内部,就通过@Import({EurekaServerMarkerConfiguration.class})的eurekaServerMarkerBean这个方法,创建的Marker对象,在这里其实相当于一个检查的作用,只有存在 Marker 实例的时候,才会继续加载配置项,这也就要求必须有 @EnableEurekaServer 注解,才能正常的启动。
4.@EnableConfigurationProperties({EurekaDashboardProperties.class, InstanceRegistryProperties.class})
这个就是导入EurekaDashboardProperties和InstanceRegistryProperties两个配置类
5.@PropertySource({"classpath:/eureka/server.properties"})
加载这个文件,值得注意的是,这个文件只有一行编码配置image.png
OK,我们来整理一下(大致流程)
image.png
我们看EurekaServerAutoConfiguration内部,它下面加载了很多的Bean对象





PeerEurekaNodes的start方法,创建的一个线程池,更新节点信息(因为eureka节点信息会发生变化)

那这个方法什么时候启动呢,我们会到主类中


PostConstruct表明会在容器构建好后执行,而this.peerEurekaNodes.start()就把上面的线程池启动了,一步套一步啊

咱们再回到主配置类中



上面的过滤器的实现,不用说也知道,是仪表盘的一些资源的过滤配置
我们回来,看EurekaServerBootstrap这个了类的contextInitialized方法

this.initEurekaEnvironment();没啥好看的啦,里面都是一些setProperty赋值一类的操作
重点关注this.initEurekaServerContext();

EurekaServerContextHolder.initialize(this.serverContext);为非ioc容器增加Context,里面是个静态变量,如果不是ioc容器,也可以拿到EurekaServerContext对象啦
this.registry.syncUp();每一个server启动的时候,从集群中其他的server拷贝注册信息同步过来,每一个server对于其他server来说也是客户端
EurekaMonitors.registerAllStats();服务注册统计器
研究一下图上的this.registry.syncUp()方法

我们再看this.register方法

再看openForTraffic方法


至此,一些细节东西均已暴露,bean改加载也加载了
启动流程EurekaServerInitializerConfiguration 实现了SmartLifecycle.start方法,在spring 初始化的时候,会被调用start,start内部 eurekaServerBootstrap.contextInitialized方法,然后呢this.initEurekaEnvironment() 初始化执行环境,this.initEurekaServerContext()初始化上下文,initEurekaServerContext方法 syncUp从邻近的eureka节点复制注册表,registerAllStats注册所有监控统计信息,至此,EurekaServer启动完毕。
eureka server服务接口暴露
现在server端已经启动完成,这个时候,该client端想server注册自己的信息,现在让我们来分析一下。

可以看到注入的对象是Application那Application是哪来的呢,看下面

那扫描的是那些包呢,其实已经定于好了

来看com.netflix.eureka这个包,它是eureka-core的核心逻辑,我们知道eureka是基于http的,它的服务端和client也是http通信,在resources包下对外提供资源的controller类

来看一下ApplicationResource类的addInstance方法,添加节点

它的核心方法this.registry.register

super.register方法就比较长了,上面也有贴到过,这里就不贴了,简单说,就是注册实例(加锁->从registry取当前的节点名的所有实例信息(相当于之前注册过的),统计节点信息,如果registry是null,就新建(其实是和map)->拿到实例之后保留最后一个时间戳/如果没有实例,就说明是新的实例注册的,就把续约数加2,因为30s一个,把当前的实例信息都放到map中->根据overriddenInstanceStatus设置状态->节点设置到recentlyChangedQueue中->设置修改时间->使Cache失效。
其实map还是厉害啊
我们回到PeerAwareInstanceRegistryImpl类,看this.replicateToPeers方法,主要是复制节点

再看this.replicateInstanceActionsToPeers方法

可以看到,不同状态,他执行不同的方法
eureka server服务接口续约


我们再点进去

replicateToPeers内部还是循环执行同步方法replicateInstanceActionsToPeers,而renew方法,本质就是对时间戳进行一个更新
网友评论