EurekaServer自动装配及启动流程解析
在开始本篇文章之前,我想你对SpringCloud和SpringBoot的基本使用已经比较熟悉了,如果不熟悉的话可以参考我之前写过的文章
本篇文章的源码基于SpringBoot2.0,SpringCloud的Finchley.RELEASE
@EnableEurekaServer注解
我们知道,在使用Eureka作为注册中心的时候,我们会在启动类中增加一个@EnableEurekaServer注解,这个注解我们是一个自定义的EnableXXX系列的注解,主要作用我们之前也多次提到了,就是引入配置类而已。看一下源码吧
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({EurekaServerMarkerConfiguration.class})
public @interface EnableEurekaServer {
}
引入了一个配置类EurekaServerMarkerConfiguration,看一下这个类的具体内容
@Configuration
public class EurekaServerMarkerConfiguration {
@Bean
public Marker eurekaServerMarkerBean() {
return new Marker();
}
class Marker {
}
}
现在看这里好像难以理解,这是啥意思,搞个空的类干啥的,不要着急,接着往下看
自动装配
既然注解上没有找到我们想要的东西,那么就看一下spring.factories文件吧,这里自动配置的实现类是EurekaServerAutoConfiguration
由于这个类涉及的代码实在是太多了,这里就不贴了,咱们直接来解析这个类:
1. 引入EurekaServerInitializerConfiguration类
看名字就知道了这个类是负责Eureka的初始化工作的,这个类实现了SmartLifecycle接口,所以在spring初始化和销毁的时候,就会分别调用它的start和stop方法
首先看一下start方法
public void start() {
new Thread(new Runnable() {
@Override
public void run() {
try {
//启动EurekaServer
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();
}
这个代码好像比较直接了当啊,直接就起个线程启动了EurekaServer,然后发布了一些启动事件,来看启动的过程吧
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);
}
}
这里一共包含初始化环境和初始化上下文两个分支
初始化执行环境
这个不是很重要,可以过滤掉
protected void initEurekaEnvironment() throws Exception {
log.info("Setting the eureka configuration..");
//AWS相关的东西,可以忽略
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 环境,默认为test
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);
}
}
初始化上下文
protected void initEurekaServerContext() throws Exception {
// 设置json与xml序列化工具
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();
}
这个方法中同步集群数据和注册监控信息都涉及的内容比较多,所以本篇文章就不再展开了,请关注我留意后续文章
@ConditionalOnBean({Marker.class})
看到这里就揭开了开篇@EnableEurekaServer注解注入的那个bean的含义了。也就是说如果咱们的启动类没有使用@EnableEurekaServer注解的话,这个自动配置类就不会执行,那也就没有Eureka的事了
@EnableConfigurationProperties({EurekaDashboardProperties.class, InstanceRegistryProperties.class})
深入这个注解发现这个还是使用的@Import注解的机制引入了两个类,这个注解在之前的源码解析文章中也多次提到了,这里就不展开了
EurekaDashboardProperties这个类比较简单,主要是Eureka的控制台的相关配置
//控制台默认路径
private String path = "/";
//是否开启控制台
private boolean enabled = true;
InstanceRegistryProperties,这个类是控制Eureka的注册时的配置信息
//每分钟续约次数
@Value("${eureka.server.expectedNumberOfRenewsPerMin:1}")
private int expectedNumberOfRenewsPerMin = 1;
//默认打开的通信数量
@Value("${eureka.server.defaultOpenForTrafficCount:1}")
private int defaultOpenForTrafficCount = 1;
@PropertySource("classpath:/eureka/server.properties")
相信大家比较熟悉这个注解,加载Eureka的配置文件而已
配置文件中也仅仅只包含这个信息
spring.http.encoding.force=false
自动注入的bean
EurekaServerAutoConfiguration类上几个注解就解析完了,接着看一下这个类中注入的几个比较重要的类吧
配置类EurekaServerConfigBeanConfiguration
EurekaServerConfig
如果当前应用允许注册到其他Eureka服务中时,也就是属性eureka.client.fetch-registry为true时。就设置属性registrySyncRetries的值为5,这个属性的意思是当Eureka服务器启动时尝试去获取集群里其他服务器上的注册信息的次数
EurekaController
这个就是Eureka自己的controller了,控制台的相关信息就是从这里获取的
ServerCodecs
设置Eureka的序列化工具
PeerAwareInstanceRegistry
集群注册信息同步相关的类,请期待后续深入解析文章
FilterRegistrationBean
EurekaServer接受请求的一个拦截器,感兴趣的同学可以研究一下
EurekaServer自动装配及启动流程解析的更多相关文章
- EurekaClient自动装配及启动流程解析
在上篇文章中,我们简单介绍了EurekaServer自动装配及启动流程解析,本篇文章则继续研究EurekaClient的相关代码 老规矩,先看spring.factories文件,其中引入了一个配置类 ...
- SpringBoot启动流程解析
写在前面: 由于该系统是底层系统,以微服务形式对外暴露dubbo服务,所以本流程中SpringBoot不基于jetty或者tomcat等容器启动方式发布服务,而是以执行程序方式启动来发布(参考下图ke ...
- Arm启动流程解析
谈到arm的启动流程不得不说的是bootloader,但是我这篇文章主要来谈谈arm启动流程的,所以bootloader只是跟大家简介一下就ok.这篇文章我会谈到以下内容: 1.bootloader简 ...
- 史上最全且最简洁易懂的Activity启动流程解析
Activity的启动流程是一个资深Android工程师必须掌握的内容,也是高职级面试中的高频面试知识点,无论是从事应用层开发,还是Framework开发,其重要性都无需我多言.而要真正理解它,就不可 ...
- “无处不在” 的系统核心服务 —— ActivityManagerService 启动流程解析
本文基于 Android 9.0 , 代码仓库地址 : android_9.0.0_r45 系列文章目录: Java 世界的盘古和女娲 -- Zygote Zygote 家的大儿子 -- System ...
- Netty(一):server启动流程解析
netty作为一个被广泛应用的通信框架,有必要我们多了解一点. 实际上netty的几个重要的技术亮点: 1. reactor的线程模型; 2. 安全有效的nio非阻塞io模型应用; 3. pipeli ...
- Spring Boot系列(二):Spring Boot自动装配原理解析
一.Spring Boot整合第三方组件(Redis为例) 1.加依赖 <!--redis--> <dependency> <groupId>org.springf ...
- Spring注解开发系列Ⅴ --- 自动装配&Profile
自动装配: spring利用依赖注入和DI完成对IOC容器中各个组件的依赖关系赋值.自动装配的优点有: 自动装配可以大大地减少属性和构造器参数的指派. 自动装配也可以在解析对象时更新配置. 自动装配的 ...
- SpringBoot自动装配-自定义Start
SpringBoot自动装配 在没有使用SpringBoot之前,使用ssm时配置redis需要在XML中配置端口号,地址,账号密码,连接池等等,而使用了SpringBoot后只需要在applicat ...
随机推荐
- 对data标签获取到的时间进行比较
前言 data(时间属性)是HTML5中新增的一个属性,常用于选择日期.时间,但这个是无法通过属性去限制其不能选择过去的时间的,这个时候就需要我们在JQ中对其进行比较了! 由于放效果图,需要在数据库里 ...
- 我所认为的RESTful API最佳实践
我所认为的RESTful API最佳实践 不要纠结于无意义的规范 在开始本文之前,我想先说这么一句:RESTful 真的很好,但它只是一种软件架构风格,过度纠结如何遵守规范只是徒增烦恼,也违背了使用它 ...
- Linux统计文件夹、文件数量的命令
# 查看当前目录下的文件数量(不包含子目录中的文件) ls -l|grep "^-"| wc -l # 查看当前目录下的文件数量(包含子目录中的文件) 注意:R,代表子目录 ls ...
- 【CobaltStrike】对CobaltStrike内置功能模块的了解
对CobaltStrike内置功能模块的了解 0x00 右键功能列表 Interact 打开beacon Access dump hashes 获取hash Elevate 提权 Golden Tic ...
- STM32HAL快速上手
STM32HAL快速上手 资料下载 如果在下面的网站中没有账户,建议用edu邮箱创建账户. STMicroeletronic 意法半导体官网 首页 - STMicroelectronics 意法半导体 ...
- itest(爱测试) 4.1.1 发布,开源BUG 跟踪管理 & 敏捷测试管理软件
v4.1.1下载地址 :itest下载 itest 简介:查看简介 itest 开源敏捷测试管理,testOps 践行者.可按测试包分配测试用例执行,也可建测试迭代(含任务,测试包,BUG)来组织测试 ...
- vue项目关闭eslint校验
[前言] eslint是一个JavaScript的校验插件,通常用来校验语法或代码的书写风格.这篇文章主要介绍了vue项目关闭eslint校验,需要的朋友可以参考下 [主体] 简介eslint esl ...
- 【转】带栗子的GDB教程
带栗子的GDB教程 原文链接:http://www.cprogramming.com/gdb.html作者:Manasij Mukherjee 一个好的调试软件是一个程序猿的工具箱里最重要的工具之一, ...
- pwn-pwn4
依旧是先检查文件的类型和保护 64位没有保护 用IDA看看,read存在溢出,溢出0x18(不懂可以翻阅前面的博客) 函数system可以调用指令 shift+F12看看 $0在Linux中是she ...
- Pwn-level0
题目地址 https://dn.jarvisoj.com/challengefiles/level0.b9ded3801d6dd36a97468e128b81a65d 第一步先看文件的属性 64 ...