Eureka源码中Server启动流程是如何具体实现的?

2026-05-25 22:591阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3003个文字,预计阅读时间需要13分钟。

Eureka源码中Server启动流程是如何具体实现的?

目录 + 环境 + 1. Spring Cloud整合Eureka Server + demo + 1.1 新建Spring Boot项目 + pom.xml文件添加 + 配置文件 + 1.2 启动类 + 1.3 启动 + 2. Spring Cloud自动装配Eureka Server + 2.1 @EnableEurekaServer注解 + 2.2 EurekaServerAu

目录
  • 环境
  • 1.spring cloud整合eureka server demo
    • 1.1 新建spring boot项目
      • pom.xml文件添加
      • 配置文件
    • 1.2 启动类
      • 1.3 启动
      • 2. spring cloud自动装配eureka server源码解析
        • 2.1 @EnableEurekaServer注解
          • 2.2 EurekaServerAutoConfiguration
            • 2.2.1 查找starter 自动装配类的技巧
            • 2.2.2 EurekaServerAutoConfiguration源码解析
        • 3. eureka server 初始化源码解析
          • 3.1 EurekaServerInitializerConfiguration
            • 3.2 DefaultEurekaServerContext

            环境

            • eureka版本:1.10.11
            • Spring Cloud : 2020.0.2
            • Spring Boot :2.4.4
              测试demo代码:github.com/hsfxuebao/s…

            本文主要看看spring cloud是怎样自动装配eureka server 并启动eureka server的并解析其关键源码。首先我们会配置启动一个spring cloud eureka server 服务,接着看看是spring cloud怎样自动装配eureka的,并看看一些核心组件的创建源码,最后解析下eureka server 启动初始化流程,看看都干了些啥东西

            1.spring cloud整合eureka server demo

            1.1 新建spring boot项目

            pom.xml文件添加

            用来规范spring cloud 的版本:

            Eureka源码中Server启动流程是如何具体实现的?

            <dependencyManagement> <!--引入springcloud依赖的--> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2020.0.2E</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

            添加用到的依赖:

            <dependencies> <!--web依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-commons</artifactId> </dependency> <!--unit test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!--spring cloud eureka server 依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>

            配置文件

            eureka: instance: hostname: localhost client: service-url: # eureka server 的地址, 咱们单实例模式就写自己好了 defaultZone: localhost:7000/eureka register-with-eureka: false # 不向eureka server 注册自己 fetch-registry: false # 不向eureka server 获取服务列表

            1.2 启动类

            @SpringBootApplication @EnableEurekaServer public class EurekaServer { public static void main(String[] args) { SpringApplication.run(EurekaServer.class, args); } }

            添加@EnableEurekaServer注解,表示它是个eureka server

            1.3 启动

            访问地址:localhost:7000/

            注意:由于是源码解析的文章,更详细的配置可以查看github.com/hsfxuebao/s…

            2. spring cloud自动装配eureka server源码解析

            2.1 @EnableEurekaServer注解

            上一节配置eureka server的时候我们在配置类上加了个@EnableEurekaServer注解,表示启动一个eureka server 。 我们看看这个注解

            @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(EurekaServerMarkerConfiguration.class) public @interface EnableEurekaServer { }

            上面有个@Import(EurekaServerMarkerConfiguration.class) 注解导入了EurekaServerMarkerConfiguration配置类,我们看下配置类:

            @Configuration public class EurekaServerMarkerConfiguration { @Bean public Marker eurekaServerMarkerBean() { return new Marker(); } class Marker { } }

            就是创建了一个EurekaServerMarkerConfiguration.Marker 对象,交给spring保管,一看就是个标记,标识,仅仅是个标识。

            2.2 EurekaServerAutoConfiguration

            2.2.1 查找starter 自动装配类的技巧

            spring boot的starter基本都会自动装配类,也就是AutoConfiguration 结尾的类,如果我们找不到某个starter的自动装配类是那个,可以去starter对应jar 包里面META-INF 文件夹下面找spring.factories (这是spring spi 配置文件)文件。比如说我可以在spring-cloud-netflix-eureka-server 这个项目下找到META-INF 文件夹下面找spring.factories文件。

            文件内容就是上图里面的,可以看到自动装配类就是EurekaServerAutoConfiguration

            2.2.2 EurekaServerAutoConfiguration源码解析

            首先,看看 EurekaServerAutoConfiguration 自动配置类里面都干了啥。

            @Configuration @Import(EurekaServerInitializerConfiguration.class) @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) @EnableConfigurationProperties({ EurekaDashboardProperties.class, InstanceRegistryProperties.class }) @PropertySource("classpath:/eureka/server.properties") public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter{}

            先看看类上面声明的这一堆注解:

            • @Import(EurekaServerInitializerConfiguration.class) : 导入(装配)配置类EurekaServerInitializerConfiguration,这个我们后面看下,属于初始化流程。
            • @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) 就是是否存在EurekaServerMarkerConfiguration.Marker 类的bean实例,这个肯定存在的,我们在@EnableEurekaServer 注解中就创建了这么一个bean 交给spring 管理了。存在就会往下走,不存在就拉倒了,不会再加载配置类里面别的东西了,也就是不会自动启动eureka server了。
            • @EnableConfigurationProperties({ EurekaDashboardProperties.class, InstanceRegistryProperties.class }) 这个就是装配这两个配置类,一个是关于Dashboard 的,一个是关于instance 的配置,也就是eureka server的配置, 就是将我们写在application.yml配置文件中关于eureka 的配置set到这里面的属性中。
            • @PropertySource(“classpath:/eureka/server.properties”) 加载/eureka/server.properties 配置文件,这个没啥意思。

            然后,看看里面成员有哪些。

            @Autowired private ApplicationInfoManager applicationInfoManager; @Autowired private EurekaServerConfig eurekaServerConfig; @Autowired private EurekaClientConfig eurekaClientConfig; @Autowired private EurekaClient eurekaClient; @Autowired private InstanceRegistryProperties instanceRegistryProperties;

            ApplicationInfoManager / EurekaClientConfig / EurekaClient 这几个bean 一看就是eureka client 里面的,我们这里是eureka server ,为啥能够注入进来呢?

            • 原因是 eureka server 的starter 里面依赖了eureka client starter,eureka client starter自动装配的这些实例bean 。有些小伙伴可能会有疑问,我启用(自动装配)eureka client,不需要在配置类上面添加@EnableEurekaClient注解嘛。其实从spring cloud netflix 1.4版本往后主要引入了这个 eureka client starter 依赖,就会自动装配,不需要添加@EnableEurekaClient 注解也是可以的。

            接着,看看创建了哪些核心组件

            dashboard 的controller

            @Bean @ConditionalOnProperty(prefix = "eureka.dashboard", name = "enabled", matchIfMissing = true) public EurekaController eurekaController() { return new EurekaController(this.applicationInfoManager); }

            注册表创建

            @Bean public PeerAwareInstanceRegistry peerAwareInstanceRegistry( ServerCodecs serverCodecs) { this.eurekaClient.getApplications(); // force initialization return new InstanceRegistry(this.eurekaServerConfig, this.eurekaClientConfig, serverCodecs, this.eurekaClient, this.instanceRegistryProperties.getExpectedNumberOfClientsSendingRenews(), this.instanceRegistryProperties.getDefaultOpenForTrafficCount()); }

            注册表,就是存放我们注册的实例信息的,这个是个非常核心的组件。这里直接创建了一个InstanceRegistry 对象,这个InstanceRegistry继承eureka server 里面PeerAwareInstanceRegistryImpl 类。

            集群节点信息类对象

            @Bean @ConditionalOnMissingBean public PeerEurekaNodes peerEurekaNodes(PeerAwareInstanceRegistry registry, ServerCodecs serverCodecs) { return new RefreshablePeerEurekaNodes(registry, this.eurekaServerConfig, this.eurekaClientConfig, serverCodecs, this.applicationInfoManager); }

            PeerEurekaNodes 这个类,从名字上也能看出来是集群节点的类,而且是Nodes ,表示多个节点,其实里面就是封装eureka server 集群的节点们。这里是创建RefreshablePeerEurekaNodes 对象,RefreshablePeerEurekaNodes继承PeerEurekaNodes 类,实现spring 的ApplicationListener 事件监听接口,自然而然的RefreshablePeerEurekaNodes类具有了刷新集群节点信息功能(能力)。

            EurekaServerContext

            @Bean public EurekaServerContext eurekaServerContext(ServerCodecs serverCodecs, PeerAwareInstanceRegistry registry, PeerEurekaNodes peerEurekaNodes) { return new DefaultEurekaServerContext(this.eurekaServerConfig, serverCodecs, registry, peerEurekaNodes, this.applicationInfoManager); }

            EurekaServerContext 从字面上是eureka server 上下文,其实就是eureka server 启动的时候会初始化PeerEurekaNodesPeerAwareInstanceRegistry 注册表,销毁的是否停止这2个组件

            EurekaServerBootstrap

            @Bean public EurekaServerBootstrap eurekaServerBootstrap(PeerAwareInstanceRegistry registry, EurekaServerContext serverContext) { return new EurekaServerBootstrap(this.applicationInfoManager, this.eurekaClientConfig, this.eurekaServerConfig, registry, serverContext); }

            一般叫Bootstrap 的类都是那种掌管项目启动与停止的,EurekaServerBootstrap 也不例外,它里面就有contextInitialized 项目启动与contextDestroyed项目停止/销毁的方法。

            jersey框架 关于jersey框架的东西,eureka server 对外暴露rest ful接口,使用的框架就是jersey(这玩意国内很少用),作用/定位就跟我们常用的springmvc 框架差不多。

            3. eureka server 初始化源码解析

            3.1 EurekaServerInitializerConfiguration

            第2小节介绍 spring cloud eureka server 启动的时候自动装配的一些组件,本小节就看下eureka server的初始化流程。

            在自动装配类EurekaServerAutoConfiguration 类上面声明了@Import(EurekaServerInitializerConfiguration.class) ,我们介绍说是导入(加载)EurekaServerInitializerConfiguration 这个配置,一看这个类名字就是eureka server 初始化用的。

            @Configuration public class EurekaServerInitializerConfiguration implements ServletContextAware, SmartLifecycle, Ordered { }

            @Configuration是个配置类,实现ServletContextAware,SmartLifecycle,Ordered 接口:

            • ServletContextAware 作用是自动注入ServletContext 实例。
            • SmartLifecycle接口 属于spring 声明周期的,start 方法执行时机是,当spring 的bean都实例化,初始化完事后,会调用SmartLifecycle 的start方法,isAutoStartup 方法返回的true 或者false 决定要不要执行start方法,这里isAutoStartup方法返回的true。
            • stop 方法就是项目停止,容器销毁的时候会调用。

            先来看下start 方法干了啥

            @Override public void start() { new Thread(new Runnable() { @Override public void run() { try { //TODO: is this class even needed now? eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext); log.info("Started Eureka Server"); publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig())); EurekaServerInitializerConfiguration.this.running = true; publish(new EurekaServerStartedEvent(getEurekaServerConfig())); } catch (Exception ex) { // Help! log.error("Could not initialize Eureka servlet context", ex); } } }).start(); }

            创建了一个线程,先是执行eurekaServerBootstrapcontextInitialized 初始化方法。接着就是发布 EurekaRegistryAvailableEvent 事件,设置running 为true ,最后就是发布EurekaServerStartedEvent 事件。 这里我们只关心eurekaServerBootstrap的contextInitialized 方法。

            public void contextInitialized(ServletContext context) { initEurekaEnvironment(); initEurekaServerContext(); context.setAttribute(EurekaServerContext.class.getName(), this.serverContext); }

            初始化eureka environment, 接着初始化context,最后是将context塞到 ServletContext的属性中。 initEurekaEnvironment这个我们就不看了。主要看下initEurekaServerContext 方法:

            if (isAws(this.applicationInfoManager.getInfo())) { this.awsBinder = new AwsBinderDelegate(this.eurekaServerConfig, this.eurekaClientConfig, this.registry, this.applicationInfoManager); this.awsBinder.start(); } EurekaServerContextHolder.initialize(this.serverContext); log.info("Initialized server context"); // Copy registry from neighboring eureka node int registryCount = this.registry.syncUp(); this.registry.openForTraffic(this.applicationInfoManager, registryCount); // Register all monitoring statistics. EurekaMonitors.registerAllStats();

            isAws 是亚马逊云环境的时候执行if里面的那一堆,这个不看了。

            EurekaServerContextHolder.initialize(this.serverContext);这行代码没干啥。

            int registryCount = this.registry.syncUp(); this.registry.openForTraffic(this.applicationInfoManager, registryCount);

            registry.syncUp()这个就是去集群中的其他节点拉取注册表。下篇文章分析 registry.openForTraffic()这个是Server端定时清理过期的Client。以后在详细分析。

            3.2 DefaultEurekaServerContext

            我们在介绍自动装配类EurekaServerAutoConfiguration 装配组件的时候,介绍过EurekaServerContext ,说他字面上是eureka server 上下文,其实就是eureka server 启动的时候会初始化PeerEurekaNodes 与PeerAwareInstanceRegistry 注册表,销毁的是否停止这2个组件 我们来看下 @PostConstruct 注解修饰的initialize 方法

            @PostConstruct public void initialize() { this.peerEurekaNodes.start(); this.registry.init(this.peerEurekaNodes); }

            干了2件事,启动peerEurekaNodes ,初始化注册表。 peerEurekaNodes#start:

            public void start() { updatePeerEurekaNodes(resolvePeerUrls()); Runnable peersUpdateTask = new Runnable() { @Override public void run() { updatePeerEurekaNodes(resolvePeerUrls()); } }; taskExecutor.scheduleWithFixedDelay( peersUpdateTask, serverConfig.getPeerEurekaNodesUpdateIntervalMs(), serverConfig.getPeerEurekaNodesUpdateIntervalMs(), TimeUnit.MILLISECONDS ); }

            先是更新集群节点信息,就是创建节点对象。

            接着就是创建一个定时任务更新,默认是10分钟。

            注册表初始化:

            @Override public void init(PeerEurekaNodes peerEurekaNodes) throws Exception { this.numberOfReplicationsLastMin.start(); this.peerEurekaNodes = peerEurekaNodes; initializedResponseCache(); scheduleRenewalThresholdUpdateTask(); initRemoteRegionRegistry(); }

            • numberOfReplicationsLastMin 这是记录续约次数的一个组件,用在服务剔除。
            • initializedResponseCache 初始化响应cache ,这个其实就是 服务发现的时候三级缓存。

            参考

            eureka-0.10.11源码(注释)

            springcloud-source-study学习github地址

            以上就是Eureka源码阅读解析Server服务端启动流程实例的详细内容,更多关于Eureka Server服务端启动流程的资料请关注自由互联其它相关文章!

            本文共计3003个文字,预计阅读时间需要13分钟。

            Eureka源码中Server启动流程是如何具体实现的?

            目录 + 环境 + 1. Spring Cloud整合Eureka Server + demo + 1.1 新建Spring Boot项目 + pom.xml文件添加 + 配置文件 + 1.2 启动类 + 1.3 启动 + 2. Spring Cloud自动装配Eureka Server + 2.1 @EnableEurekaServer注解 + 2.2 EurekaServerAu

            目录
            • 环境
            • 1.spring cloud整合eureka server demo
              • 1.1 新建spring boot项目
                • pom.xml文件添加
                • 配置文件
              • 1.2 启动类
                • 1.3 启动
                • 2. spring cloud自动装配eureka server源码解析
                  • 2.1 @EnableEurekaServer注解
                    • 2.2 EurekaServerAutoConfiguration
                      • 2.2.1 查找starter 自动装配类的技巧
                      • 2.2.2 EurekaServerAutoConfiguration源码解析
                  • 3. eureka server 初始化源码解析
                    • 3.1 EurekaServerInitializerConfiguration
                      • 3.2 DefaultEurekaServerContext

                      环境

                      • eureka版本:1.10.11
                      • Spring Cloud : 2020.0.2
                      • Spring Boot :2.4.4
                        测试demo代码:github.com/hsfxuebao/s…

                      本文主要看看spring cloud是怎样自动装配eureka server 并启动eureka server的并解析其关键源码。首先我们会配置启动一个spring cloud eureka server 服务,接着看看是spring cloud怎样自动装配eureka的,并看看一些核心组件的创建源码,最后解析下eureka server 启动初始化流程,看看都干了些啥东西

                      1.spring cloud整合eureka server demo

                      1.1 新建spring boot项目

                      pom.xml文件添加

                      用来规范spring cloud 的版本:

                      Eureka源码中Server启动流程是如何具体实现的?

                      <dependencyManagement> <!--引入springcloud依赖的--> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2020.0.2E</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

                      添加用到的依赖:

                      <dependencies> <!--web依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-commons</artifactId> </dependency> <!--unit test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!--spring cloud eureka server 依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>

                      配置文件

                      eureka: instance: hostname: localhost client: service-url: # eureka server 的地址, 咱们单实例模式就写自己好了 defaultZone: localhost:7000/eureka register-with-eureka: false # 不向eureka server 注册自己 fetch-registry: false # 不向eureka server 获取服务列表

                      1.2 启动类

                      @SpringBootApplication @EnableEurekaServer public class EurekaServer { public static void main(String[] args) { SpringApplication.run(EurekaServer.class, args); } }

                      添加@EnableEurekaServer注解,表示它是个eureka server

                      1.3 启动

                      访问地址:localhost:7000/

                      注意:由于是源码解析的文章,更详细的配置可以查看github.com/hsfxuebao/s…

                      2. spring cloud自动装配eureka server源码解析

                      2.1 @EnableEurekaServer注解

                      上一节配置eureka server的时候我们在配置类上加了个@EnableEurekaServer注解,表示启动一个eureka server 。 我们看看这个注解

                      @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(EurekaServerMarkerConfiguration.class) public @interface EnableEurekaServer { }

                      上面有个@Import(EurekaServerMarkerConfiguration.class) 注解导入了EurekaServerMarkerConfiguration配置类,我们看下配置类:

                      @Configuration public class EurekaServerMarkerConfiguration { @Bean public Marker eurekaServerMarkerBean() { return new Marker(); } class Marker { } }

                      就是创建了一个EurekaServerMarkerConfiguration.Marker 对象,交给spring保管,一看就是个标记,标识,仅仅是个标识。

                      2.2 EurekaServerAutoConfiguration

                      2.2.1 查找starter 自动装配类的技巧

                      spring boot的starter基本都会自动装配类,也就是AutoConfiguration 结尾的类,如果我们找不到某个starter的自动装配类是那个,可以去starter对应jar 包里面META-INF 文件夹下面找spring.factories (这是spring spi 配置文件)文件。比如说我可以在spring-cloud-netflix-eureka-server 这个项目下找到META-INF 文件夹下面找spring.factories文件。

                      文件内容就是上图里面的,可以看到自动装配类就是EurekaServerAutoConfiguration

                      2.2.2 EurekaServerAutoConfiguration源码解析

                      首先,看看 EurekaServerAutoConfiguration 自动配置类里面都干了啥。

                      @Configuration @Import(EurekaServerInitializerConfiguration.class) @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) @EnableConfigurationProperties({ EurekaDashboardProperties.class, InstanceRegistryProperties.class }) @PropertySource("classpath:/eureka/server.properties") public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter{}

                      先看看类上面声明的这一堆注解:

                      • @Import(EurekaServerInitializerConfiguration.class) : 导入(装配)配置类EurekaServerInitializerConfiguration,这个我们后面看下,属于初始化流程。
                      • @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) 就是是否存在EurekaServerMarkerConfiguration.Marker 类的bean实例,这个肯定存在的,我们在@EnableEurekaServer 注解中就创建了这么一个bean 交给spring 管理了。存在就会往下走,不存在就拉倒了,不会再加载配置类里面别的东西了,也就是不会自动启动eureka server了。
                      • @EnableConfigurationProperties({ EurekaDashboardProperties.class, InstanceRegistryProperties.class }) 这个就是装配这两个配置类,一个是关于Dashboard 的,一个是关于instance 的配置,也就是eureka server的配置, 就是将我们写在application.yml配置文件中关于eureka 的配置set到这里面的属性中。
                      • @PropertySource(“classpath:/eureka/server.properties”) 加载/eureka/server.properties 配置文件,这个没啥意思。

                      然后,看看里面成员有哪些。

                      @Autowired private ApplicationInfoManager applicationInfoManager; @Autowired private EurekaServerConfig eurekaServerConfig; @Autowired private EurekaClientConfig eurekaClientConfig; @Autowired private EurekaClient eurekaClient; @Autowired private InstanceRegistryProperties instanceRegistryProperties;

                      ApplicationInfoManager / EurekaClientConfig / EurekaClient 这几个bean 一看就是eureka client 里面的,我们这里是eureka server ,为啥能够注入进来呢?

                      • 原因是 eureka server 的starter 里面依赖了eureka client starter,eureka client starter自动装配的这些实例bean 。有些小伙伴可能会有疑问,我启用(自动装配)eureka client,不需要在配置类上面添加@EnableEurekaClient注解嘛。其实从spring cloud netflix 1.4版本往后主要引入了这个 eureka client starter 依赖,就会自动装配,不需要添加@EnableEurekaClient 注解也是可以的。

                      接着,看看创建了哪些核心组件

                      dashboard 的controller

                      @Bean @ConditionalOnProperty(prefix = "eureka.dashboard", name = "enabled", matchIfMissing = true) public EurekaController eurekaController() { return new EurekaController(this.applicationInfoManager); }

                      注册表创建

                      @Bean public PeerAwareInstanceRegistry peerAwareInstanceRegistry( ServerCodecs serverCodecs) { this.eurekaClient.getApplications(); // force initialization return new InstanceRegistry(this.eurekaServerConfig, this.eurekaClientConfig, serverCodecs, this.eurekaClient, this.instanceRegistryProperties.getExpectedNumberOfClientsSendingRenews(), this.instanceRegistryProperties.getDefaultOpenForTrafficCount()); }

                      注册表,就是存放我们注册的实例信息的,这个是个非常核心的组件。这里直接创建了一个InstanceRegistry 对象,这个InstanceRegistry继承eureka server 里面PeerAwareInstanceRegistryImpl 类。

                      集群节点信息类对象

                      @Bean @ConditionalOnMissingBean public PeerEurekaNodes peerEurekaNodes(PeerAwareInstanceRegistry registry, ServerCodecs serverCodecs) { return new RefreshablePeerEurekaNodes(registry, this.eurekaServerConfig, this.eurekaClientConfig, serverCodecs, this.applicationInfoManager); }

                      PeerEurekaNodes 这个类,从名字上也能看出来是集群节点的类,而且是Nodes ,表示多个节点,其实里面就是封装eureka server 集群的节点们。这里是创建RefreshablePeerEurekaNodes 对象,RefreshablePeerEurekaNodes继承PeerEurekaNodes 类,实现spring 的ApplicationListener 事件监听接口,自然而然的RefreshablePeerEurekaNodes类具有了刷新集群节点信息功能(能力)。

                      EurekaServerContext

                      @Bean public EurekaServerContext eurekaServerContext(ServerCodecs serverCodecs, PeerAwareInstanceRegistry registry, PeerEurekaNodes peerEurekaNodes) { return new DefaultEurekaServerContext(this.eurekaServerConfig, serverCodecs, registry, peerEurekaNodes, this.applicationInfoManager); }

                      EurekaServerContext 从字面上是eureka server 上下文,其实就是eureka server 启动的时候会初始化PeerEurekaNodesPeerAwareInstanceRegistry 注册表,销毁的是否停止这2个组件

                      EurekaServerBootstrap

                      @Bean public EurekaServerBootstrap eurekaServerBootstrap(PeerAwareInstanceRegistry registry, EurekaServerContext serverContext) { return new EurekaServerBootstrap(this.applicationInfoManager, this.eurekaClientConfig, this.eurekaServerConfig, registry, serverContext); }

                      一般叫Bootstrap 的类都是那种掌管项目启动与停止的,EurekaServerBootstrap 也不例外,它里面就有contextInitialized 项目启动与contextDestroyed项目停止/销毁的方法。

                      jersey框架 关于jersey框架的东西,eureka server 对外暴露rest ful接口,使用的框架就是jersey(这玩意国内很少用),作用/定位就跟我们常用的springmvc 框架差不多。

                      3. eureka server 初始化源码解析

                      3.1 EurekaServerInitializerConfiguration

                      第2小节介绍 spring cloud eureka server 启动的时候自动装配的一些组件,本小节就看下eureka server的初始化流程。

                      在自动装配类EurekaServerAutoConfiguration 类上面声明了@Import(EurekaServerInitializerConfiguration.class) ,我们介绍说是导入(加载)EurekaServerInitializerConfiguration 这个配置,一看这个类名字就是eureka server 初始化用的。

                      @Configuration public class EurekaServerInitializerConfiguration implements ServletContextAware, SmartLifecycle, Ordered { }

                      @Configuration是个配置类,实现ServletContextAware,SmartLifecycle,Ordered 接口:

                      • ServletContextAware 作用是自动注入ServletContext 实例。
                      • SmartLifecycle接口 属于spring 声明周期的,start 方法执行时机是,当spring 的bean都实例化,初始化完事后,会调用SmartLifecycle 的start方法,isAutoStartup 方法返回的true 或者false 决定要不要执行start方法,这里isAutoStartup方法返回的true。
                      • stop 方法就是项目停止,容器销毁的时候会调用。

                      先来看下start 方法干了啥

                      @Override public void start() { new Thread(new Runnable() { @Override public void run() { try { //TODO: is this class even needed now? eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext); log.info("Started Eureka Server"); publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig())); EurekaServerInitializerConfiguration.this.running = true; publish(new EurekaServerStartedEvent(getEurekaServerConfig())); } catch (Exception ex) { // Help! log.error("Could not initialize Eureka servlet context", ex); } } }).start(); }

                      创建了一个线程,先是执行eurekaServerBootstrapcontextInitialized 初始化方法。接着就是发布 EurekaRegistryAvailableEvent 事件,设置running 为true ,最后就是发布EurekaServerStartedEvent 事件。 这里我们只关心eurekaServerBootstrap的contextInitialized 方法。

                      public void contextInitialized(ServletContext context) { initEurekaEnvironment(); initEurekaServerContext(); context.setAttribute(EurekaServerContext.class.getName(), this.serverContext); }

                      初始化eureka environment, 接着初始化context,最后是将context塞到 ServletContext的属性中。 initEurekaEnvironment这个我们就不看了。主要看下initEurekaServerContext 方法:

                      if (isAws(this.applicationInfoManager.getInfo())) { this.awsBinder = new AwsBinderDelegate(this.eurekaServerConfig, this.eurekaClientConfig, this.registry, this.applicationInfoManager); this.awsBinder.start(); } EurekaServerContextHolder.initialize(this.serverContext); log.info("Initialized server context"); // Copy registry from neighboring eureka node int registryCount = this.registry.syncUp(); this.registry.openForTraffic(this.applicationInfoManager, registryCount); // Register all monitoring statistics. EurekaMonitors.registerAllStats();

                      isAws 是亚马逊云环境的时候执行if里面的那一堆,这个不看了。

                      EurekaServerContextHolder.initialize(this.serverContext);这行代码没干啥。

                      int registryCount = this.registry.syncUp(); this.registry.openForTraffic(this.applicationInfoManager, registryCount);

                      registry.syncUp()这个就是去集群中的其他节点拉取注册表。下篇文章分析 registry.openForTraffic()这个是Server端定时清理过期的Client。以后在详细分析。

                      3.2 DefaultEurekaServerContext

                      我们在介绍自动装配类EurekaServerAutoConfiguration 装配组件的时候,介绍过EurekaServerContext ,说他字面上是eureka server 上下文,其实就是eureka server 启动的时候会初始化PeerEurekaNodes 与PeerAwareInstanceRegistry 注册表,销毁的是否停止这2个组件 我们来看下 @PostConstruct 注解修饰的initialize 方法

                      @PostConstruct public void initialize() { this.peerEurekaNodes.start(); this.registry.init(this.peerEurekaNodes); }

                      干了2件事,启动peerEurekaNodes ,初始化注册表。 peerEurekaNodes#start:

                      public void start() { updatePeerEurekaNodes(resolvePeerUrls()); Runnable peersUpdateTask = new Runnable() { @Override public void run() { updatePeerEurekaNodes(resolvePeerUrls()); } }; taskExecutor.scheduleWithFixedDelay( peersUpdateTask, serverConfig.getPeerEurekaNodesUpdateIntervalMs(), serverConfig.getPeerEurekaNodesUpdateIntervalMs(), TimeUnit.MILLISECONDS ); }

                      先是更新集群节点信息,就是创建节点对象。

                      接着就是创建一个定时任务更新,默认是10分钟。

                      注册表初始化:

                      @Override public void init(PeerEurekaNodes peerEurekaNodes) throws Exception { this.numberOfReplicationsLastMin.start(); this.peerEurekaNodes = peerEurekaNodes; initializedResponseCache(); scheduleRenewalThresholdUpdateTask(); initRemoteRegionRegistry(); }

                      • numberOfReplicationsLastMin 这是记录续约次数的一个组件,用在服务剔除。
                      • initializedResponseCache 初始化响应cache ,这个其实就是 服务发现的时候三级缓存。

                      参考

                      eureka-0.10.11源码(注释)

                      springcloud-source-study学习github地址

                      以上就是Eureka源码阅读解析Server服务端启动流程实例的详细内容,更多关于Eureka Server服务端启动流程的资料请关注自由互联其它相关文章!