启用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. (五)CXF之添加拦截器

    一.需求分析 webService中的拦截器类似于servlet的Filter过滤器.一般用于调用服务前后先调用拦截器的方法. 二.案例 本章案例是基于上一章节的基础上添加拦截器的 2.1 服务端添加 ...

  2. (一)Redis之简介和windows下安装radis

    一.简介 1.1 关于nosql 介绍Redis之前,先了解下NoSQL (Not noly SQL)不仅仅是SQL, 属于非关系型数据库:Redis就属于非关系型数据库, 传统的Mysql ,ora ...

  3. ubuntu装openssh-client和openssh-server

    1. 修改update源 进入/etc/apt/目录,首先用cp命令将sources.list备份成sources.list.bk,然后复制http://www.cnblogs.com/eastson ...

  4. [NOIP2018模拟赛10.22]咕咕报告

    闲扯 这是篇咕咕了的博客 考场上码完暴力后不知道干什么,然后忽然发现这个T1好像有点像一道雅礼集训时讲过的CF题目 Rest In Shades ,当时那道题还想了挺久不过思路比较妙,于是我就也\(y ...

  5. 关于Vue中,checkBox等组件在赋值后,点击切换页面未及时更新问题

    我们经常碰到这样的问题,在v-for循环中,给某些组件(此处以checkBox为例)赋值后,组件并不能正常切换, 这是因为数据层太多,render函数没有自动更新,需手动强制刷新. 解决方法:在切换c ...

  6. 认识:before和:after伪类

    有时候,我们需要大量的重复代码去实现一个非常简单的功能,这不仅浪费时间,而且效率低下,例如: <div class="aa">你好</div><div ...

  7. FPGA上外挂DDR2&DDR3&MIG IP的使用记录

    前言 当需要大容量数据存储及处理的时候,FPGA内部自带的存储资源是远远不够的,所以问题来了,怎么使用外带的DDR3? 首要问题在于DDR3是什么?有没有协议?当然只是需要用Xilinx MIG IP ...

  8. linux内存管理初学

    虚拟内存模型 Linux 内核本身并不运行在虚拟空间中,其使用的是物理寻址模式. 物理内存被分割为界面,一个内存页面的大小由PAGE_SIZE宏决定. 虚拟地址空间的方式使程序员可以将巨大的结构用于连 ...

  9. nginx增加新模块

    以gunzip这个模块为例,讲述一下,在nginx中如何安装新的模块 1.首先查看nginx已经安装了哪些模块. nginx –V 2.发现没有gunzip模块,安装 进入nginx的安装目录中,不是 ...

  10. 使用SQLAlchemy,以及问题处理

    https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0014021031294178 ...