启用EurekaServer

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

@EnableEurekaServer 源码:

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

将配置类 EurekaServerMarkerConfiguration 加入spring 容器。

EurekaServerMarkerConfiguration 的源码

/**
*
* 激活 EurekaServerAutoConfiguration 的开关
*/
@Configuration
public class EurekaServerMarkerConfiguration { @Bean
public Marker eurekaServerMarkerBean() {
return new Marker();
} class Marker {
}
}

我们看到只是实例化了一个空类,没有任何实现,从注释中可以看到 EurekaServerMarkerConfiguration 是一个激活 EurekaServerAutoConfiguration 的开关。我们在项目源码的 META-INF/spring.factories中看到

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration

真正的配置信息在 EurekaServerAutoConfiguration 中,我们看到 @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) 只有存在 Marker 实例的时候,才会继续加载配置项,这也就要求必须有 @EnableEurekaServer 注解,才能正常的启动。

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

简单的梳理一下 @EnableEurekaServer 的流程为:

import
扫描到
条件判断
加载具体配置信息
EnableEurekaServer
EurekaServerMarkerConfiguration
EurekaServerAutoConfiguration
ConditionalOnBean
EurekaServerAutoConfiguration

EurekaServerAutoConfiguration 源码

在源码中我们可以看到一个很重要的注解 @Import(EurekaServerInitializerConfiguration.class) ,该注解是真正的的启动了服务,下面我们就看一下它都有哪些操作

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

1、@Configuration 表明这是一个配置类

2、@Import(EurekaServerInitializerConfiguration.class) 导入启动EurekaServer的bean

3、@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) 这个是表示只有在spring容器

里面含有Market这个实例的时候,才会加载当前这个Bean(EurekaServerAutoConfiguration ),这个就是控制

是否开启EurekaServer的关键,

4、@EnableConfigurationProperties({ EurekaDashboardProperties.class, InstanceRegistryProperties.class })

加载配置

5、@PropertySource(“classpath:/eureka/server.properties”) 加载配置文件。

EurekaServerInitializerConfiguration 实现了SmartLifecycle.start方法,在spring 初始化的时候,会被调用

@Configuration
@CommonsLog
public class EurekaServerInitializerConfiguration
      implements ServletContextAware, SmartLifecycle, Ordered {
 
   @Autowired
   private EurekaServerConfig eurekaServerConfig;
 
   private ServletContext servletContext;
 
   @Autowired
   private ApplicationContext applicationContext;
 
   @Autowired
   private EurekaServerBootstrap eurekaServerBootstrap;
 
   private boolean running;
 
   private int order = 1;
 
   @Override
   public void setServletContext(ServletContext servletContext) {
      this.servletContext = servletContext;
   }
 
   @Override
   public void start() {
      // 启动一个线程
      new Thread(new Runnable() {
         @Override
         public void run() {
            try {
               //初始化EurekaServer,同时启动Eureka Server
               eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext);
               log.info("Started Eureka Server");
                // 发布EurekaServer的注册事件
               publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig()));
                // 设置启动的状态为true
               EurekaServerInitializerConfiguration.this.running = true;
                // 发布Eureka Start 事件,另外还有其他事件,我们可以根据需要监听这些事件,然后做一些特定的业务需求
               publish(new EurekaServerStartedEvent(getEurekaServerConfig()));
            }
            catch (Exception ex) {
              
               log.error("Could not initialize Eureka servlet context", ex);
            }
         }
      }).start();
   }
 
   private EurekaServerConfig getEurekaServerConfig() {
      return this.eurekaServerConfig;
   }
 
   private void publish(ApplicationEvent event) {
      this.applicationContext.publishEvent(event);
   }
 
   @Override
   public void stop() {
      this.running = false;
      eurekaServerBootstrap.contextDestroyed(this.servletContext);
   }
 
  .................省略...............
}

eurekaServerBootstrap是spring cloud定义的类,其代码完全拷贝了Eureka启动类的实现。 这里看到在Eureka启动后,会向外发送EurekaRegistryAvailableEvent 和 EurekaServerStartedEvent 事件,我们可以根据需要订阅这两个事件,做具体的处理操作。

接着我们一下 EurekaServerBootstrap 做了哪些具体的操作,从源码中可以看到方法 contextInitialized(ServletContext context) 进行了环境和上下文的初始化工作,下面我们分别看一下:

EurekaServerBootstrap > contextInitialized

public void contextInitialized(ServletContext context) {
try {
//初始化执行环境
initEurekaEnvironment();
//初始化上下文
initEurekaServerContext(); context.setAttribute(EurekaServerContext.class.getName(), this.serverContext);
}
catch (Throwable e) {
log.error("Cannot bootstrap eureka server :", e);
throw new RuntimeException("Cannot bootstrap eureka server :", e);
}
}

EurekaServerBootstrap > contextInitialized > initEurekaEnvironment

protected void initEurekaEnvironment() throws Exception {
log.info("Setting the eureka configuration.."); //设置数据中心
String dataCenter = ConfigurationManager.getConfigInstance()
.getString(EUREKA_DATACENTER);
if (dataCenter == null) {
log.info(
"Eureka data center value eureka.datacenter is not set, defaulting to default");
ConfigurationManager.getConfigInstance()
.setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, DEFAULT);
}
else {
ConfigurationManager.getConfigInstance()
.setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, dataCenter);
}
//设置 Eureka 环境
String environment = ConfigurationManager.getConfigInstance()
.getString(EUREKA_ENVIRONMENT);
if (environment == null) {
ConfigurationManager.getConfigInstance()
.setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST);
log.info(
"Eureka environment value eureka.environment is not set, defaulting to test");
}
else {
ConfigurationManager.getConfigInstance()
.setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, environment);
}
}

EurekaServerBootstrap > contextInitialized > initEurekaEnvironment

protected void initEurekaServerContext() throws Exception {
// For backward compatibility
JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(),
XStream.PRIORITY_VERY_HIGH);
XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(),
XStream.PRIORITY_VERY_HIGH); 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"); // 从邻近的eureka节点复制注册表
int registryCount = this.registry.syncUp();
this.registry.openForTraffic(this.applicationInfoManager, registryCount); // 注册所有监控统计信息
EurekaMonitors.registerAllStats();
}

至此,EurekaServer启动完毕, EurekaServerBootstrap是完全复制了原生EurekaBootstrap的代码, 因为原生的Eureka

是在servlet应用,但是spring cloud的应用是运行在内嵌的Tomcat等WEB服务器里面的,所以就使用EurekaServerBootstrap

来做替换,最终使Eureka能够在spring boot中使用。

Spring Cloud Eureka(五):Eureka Server 启动流程分析的更多相关文章

  1. 【spring cloud】spring cloud分布式服务eureka启动时报错:java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Object;)V

    spring cloud分布式服务eureka启动时报错:java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApp ...

  2. Spring Cloud 入门 之 Eureka 篇(一)

    原文地址:Spring Cloud 入门 之 Eureka 篇(一) 博客地址:http://www.extlight.com 一.前言 Spring Cloud 是一系列框架的有序集合.它利用 Sp ...

  3. Spring Cloud 系列之 Eureka 实现服务注册与发现

    如果你对 Spring Cloud 体系还不是很了解,可以先读一下 Spring Cloud 都有哪些模块 Eureka 是 Netflix 开源的服务注册发现组件,服务发现可以说是微服务架构的核心功 ...

  4. 基于Spring cloud Ribbon和Eureka实现客户端负载均衡

    前言 本案例将基于Spring cloud Ribbon和Eureka实现客户端负载均衡,其中Ribbon用于实现客户端负载均衡,Eureka主要是用于服务注册及发现: 传统的服务端负载均衡 常见的服 ...

  5. spring cloud config与eureka配合使用

    前面两篇介绍了Spring Cloud Config服务端和客户端的简单配置,本篇介绍Spring Cloud Config与Eureka配合使用 前言 默认情况下,配置客户端启动时,都是通过配置属性 ...

  6. Spring Cloud中,Eureka常见问题总结

    Spring Cloud中,Eureka常见问题总结. 1 eureka.environment: 指定环境 参考文档: 1 eureka.datacenter: 指定数据中心 参考文档: 使用配置项 ...

  7. Spring Cloud(五):Hystrix 监控面板【Finchley 版】

    Spring Cloud(五):Hystrix 监控面板[Finchley 版]  发表于 2018-04-16 |  更新于 2018-05-10 |  在上一篇 Hystrix 的介绍中,我们提到 ...

  8. Spring Cloud Netflix之Euraka Server注册中心

    Spring Cloud简介 Spring Cloud是基于Spring Boot的一套实现微服务架构的生态组件.生态组件中包含Spring Cloud NetFlix,Spring Cloud Fe ...

  9. SpringBoot启动流程分析(五):SpringBoot自动装配原理实现

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

随机推荐

  1. (八)装配Bean(2)

    二.在Java类中进行显式的装配 显式配置有两种: 1. 一种是在java(本文讲解)   2. 另一种是xml配置文件(第一章有讲) 案例一: 使用java显式装配+@autowired自动装配的方 ...

  2. (七)Redis之持久化之RDB方式

    一.持久化概念 所有的数据都存在内存中,从内存当中同步到硬盘上,这个过程叫做持久化过程. 使用方法: 1. rdb持久化方法:在指定的时间间隔写入硬盘 2.         aof方式:将以日志,记录 ...

  3. 补充:Python安装

    需要安装Python2.7.Numpy和Matplotlib.由于Python不支持向下兼容,因此在Python3.×下你一定能正常运行Python2.×的代码.上述模块最简单的安装方法就是用软件包安 ...

  4. 【转载】salesforce 零基础开发入门学习(一)Salesforce功能介绍,IDE配置以及资源下载

    salesforce 零基础开发入门学习(一)Salesforce功能介绍,IDE配置以及资源下载   目前国内已经有很多公司做salesforce,但是国内相关的资料确是少之又少.上个月末跳槽去了新 ...

  5. 批量删除checkbox前台后台

    <%@ page contentType="text/html;charset=UTF-8" %><%@ include file="/WEB-INF/ ...

  6. wsl2 debian安装docker

    应用商店下载debian 安装docker 安装依赖 打开安装好的docker安装依赖 sudo apt-get install apt-transport-https ca-certificates ...

  7. ELK6.x_Kafka 安装配置文档

    1. 环境描述 1.1.   环境拓扑 如上图所示:Kafka为3节点集群负责提供消息队列,ES为3节点集群.日志通过logstash或者filebeat传送至Kafka集群,再通过logstash发 ...

  8. 学习笔记:Python序列化常用工具及性能对比

    什么叫序列化?简单来讲就是将内存中的变量数据转而存储到磁盘上或是通过网络传输到远程. 反序列化是指:把变量数据从序列化的对象重新读到内存里. 下面我们一起来看看,python里面序列化常用的json. ...

  9. k2系列-服务器管理篇

    k2服务器即K2 WORKSPACE管理介绍: k2 管理平台统一管理基于K2开发的所有流程的跟踪调试以及基本配置信息. 具体完成的操作有以下几个部分: 1 配置K2环境相关属性.包括全局变量等 2 ...

  10. 7.Vue实例的生命周期

    1.Vue实例的生命周期: 什么是生命周期:从Vue实例创建.运行.到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期! 生命周期钩子 = 生命周期函数 = 生命周期事件 2. 主要的生命 ...