Spring Cloud Eureka(五):Eureka Server 启动流程分析
启用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 的流程为:
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 启动流程分析的更多相关文章
- 【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 ...
- Spring Cloud 入门 之 Eureka 篇(一)
原文地址:Spring Cloud 入门 之 Eureka 篇(一) 博客地址:http://www.extlight.com 一.前言 Spring Cloud 是一系列框架的有序集合.它利用 Sp ...
- Spring Cloud 系列之 Eureka 实现服务注册与发现
如果你对 Spring Cloud 体系还不是很了解,可以先读一下 Spring Cloud 都有哪些模块 Eureka 是 Netflix 开源的服务注册发现组件,服务发现可以说是微服务架构的核心功 ...
- 基于Spring cloud Ribbon和Eureka实现客户端负载均衡
前言 本案例将基于Spring cloud Ribbon和Eureka实现客户端负载均衡,其中Ribbon用于实现客户端负载均衡,Eureka主要是用于服务注册及发现: 传统的服务端负载均衡 常见的服 ...
- spring cloud config与eureka配合使用
前面两篇介绍了Spring Cloud Config服务端和客户端的简单配置,本篇介绍Spring Cloud Config与Eureka配合使用 前言 默认情况下,配置客户端启动时,都是通过配置属性 ...
- Spring Cloud中,Eureka常见问题总结
Spring Cloud中,Eureka常见问题总结. 1 eureka.environment: 指定环境 参考文档: 1 eureka.datacenter: 指定数据中心 参考文档: 使用配置项 ...
- Spring Cloud(五):Hystrix 监控面板【Finchley 版】
Spring Cloud(五):Hystrix 监控面板[Finchley 版] 发表于 2018-04-16 | 更新于 2018-05-10 | 在上一篇 Hystrix 的介绍中,我们提到 ...
- Spring Cloud Netflix之Euraka Server注册中心
Spring Cloud简介 Spring Cloud是基于Spring Boot的一套实现微服务架构的生态组件.生态组件中包含Spring Cloud NetFlix,Spring Cloud Fe ...
- SpringBoot启动流程分析(五):SpringBoot自动装配原理实现
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
随机推荐
- (五)CXF之添加拦截器
一.需求分析 webService中的拦截器类似于servlet的Filter过滤器.一般用于调用服务前后先调用拦截器的方法. 二.案例 本章案例是基于上一章节的基础上添加拦截器的 2.1 服务端添加 ...
- Linux每隔1秒kill掉cpu大于50%的进程
1.新建/test/killcpu.sh shell脚本 并授予权限0755#!/bin/bashps axf -o "pid %cpu" | awk '{if($2>=50 ...
- 基因组所三代单分子测序PacBio完成技术升级—超长读长助力基因组学研究
基因组所三代单分子测序PacBio完成技术升级—超长读长助力基因组学研究 2015-09-23 | 作者:所级中心基因组平台 张兵 [关闭] 近日,基因组所所级中心基因组平台三代单分子实时测序PacB ...
- \lib\cmsis\stm32f10x.h(298): error: #67: expected a "}"
首先介绍一下csdn屏蔽广告 这个至关重要,请参考 https://blog.csdn.net/qq_40881680/article/details/82226562 更新KEIL5以后,原KEIL ...
- 如何将Chrome本地安装的扩展应用导出到本地
有时由于种种原因,我们不能直接使用Chrome web store进行Chrome扩展应用的安装,这时可以让一位已经安装了某Chrome扩展应用的朋友将他的应用导出到本地成为.crx文件,然后发给你, ...
- Vue获取数据渲染完成事件
主要代码是这两坨 this.nextTick(function(){ alert('数据已经更新') }); this.$nextTick(function(){ alert('v-for渲染已经完成 ...
- python 爬虫 Selenium的简单使用
一.Selenium基础介绍及安装 1.Selenium简介 Selenium是一个用于测试网站的自动化测试工具,支持各种浏览器包括Chrome.Firefox.Safari等主流界面浏览器,同时也支 ...
- python使得文件不包含重复行
set函数去重 # -*- coding:utf-8 -*- srcTxt=open('1.txt','r').readlines() noRepeat=open('2.txt','w') st=se ...
- idou老师教你学Istio 27:解读Mixer Report流程
1.概述 Mixer是Istio的核心组件,提供了遥测数据收集的功能,能够实时采集服务的请求状态等信息,以达到监控服务状态目的. 1.1 核心功能 •前置检查(Check):某服务接收并响应外部请求前 ...
- webpack中css文件的代码分割
module.exports = { output: { filename: '[name].js', chunkFilename: '[name].chunk.js', path: path.res ...