前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图个源码系列 · eureka的初始化以及配置管理。

图个源码系列 · eureka的初始化以及配置管理。

作者头像
简熵
发布2023-03-06 21:39:43
3350
发布2023-03-06 21:39:43
举报
文章被收录于专栏:逆熵逆熵

目录

1、找到eureka的启动入口

2、配置对象的单例如何创建?

3、基于接口的配置管理

武汉加油,中国加油,相信中国力量,这个难关我们一定能度过!!!少出门,多喝水,少聚餐,勤洗手。此刻,安静地坐在窗户边开始eureka的源码解读。第二篇开始之前分享我家窗前的静静地美景,愿每个人都能与美景同行,与安心同行。

1、找到eureka的启动入口

eureka server就是一个微博应用,最终就是打成了一个war包,只要将war包放入任意的一个web容器就可以启动起来。我们也分析了web.xml这个极为关键的配置文件,在其中最为关键的一个类就是EurekaBootStrap。接下来我们就聚焦这个类,去深入eureka的启动机制。

首先EurekaBootStrap继承了ServletContextListener类,当容器启动的时候就会调用下面这个方法。

入口:我们一行一行的来分析,首先,109行初始化环境变量,进入initEurekaEnvironment()方法。

分析:127行获取数据中心配置项的值,并且将数据中心配置项的值又设置到某处,如果值不存在,就取默认值"default"。134行获取当前的环境配置项的值,如果不存在,就取默认值"test"。 这边关于配置相关的我们在下一节统一讨论

总结:这个方法主要就是对一些环境配置做了加载和设置,并且都有默认值。

02

配置对象的单例如何创建

接着上文我们开始解读eureka的配置管理是如何做的,上文中我们可以看到这样一行代码。基于码农的嗅觉,见到什么getInstance之类的第一反应就是单例,我们跟进去看看。

代码语言:javascript
复制
 String dataCenter = ConfigurationManager.getConfigInstance().getString(EUREKA_DATACENTER);

入口:ConfigurationManager.java的createDefaultConfiguration()方法

分析192-201行,静态方法,果不其然,这里是个单例,

技术亮点:还是double check + volatile的写法。保证了最终的配置对象AbstractConfiguration是个单例。

上图就是创建默认配置对象的方法,158行,直接就new了一个ConcurrentCompositeConfiguration对象config,并且在类的构造函数中执行了一些旧配置对象的清理工作,重新创建了新的配置对象以及很多子配置项。

我们也看到这其中有一些事件发布和监听者的代码。经过不断向ConcurrentCompositeConfiguration对象的父类进行追踪,发现每个级别的父类都有自己的listeners集合,也有自己的fireEvent发布事件处理的方法,包括clear方法也是都有各自的实现,并且子类也有重写的实现。

不过在本次对象ConcurrentCompositeConfiguration创建的过程中,还没看到有监听者,所以事件发布也不会进行处理,直接就return了。

到这里,主要就是new了配置对象ConcurrentCompositeConfiguration,并且对类中的一些成员变量进行了初始化,一些子配置项的清理,重新创建,构建了有层级的事件发布机制。

159-172行,创建了几个不同的配置对象,

DynamicURLConfiguration,

SystemConfiguration,

EnvironmentConfiguration,他们都是AbstractConfiguration的子类并且都添加到了上文中的config对象的configList中,并且创建了给每个配置对象都设置了监听者。当上面提到的fireEvent调用的时候就会触发。而且最终走的是EventSource的事件发布处理的逻辑。

173-176行,创建了一个名为appOverriveConfig的ConcurrentCompositeConfiguration对象,并且也设置给了上文中的那个config对象。最终将这个配置对象返回。

总结:最终一步步返回,一个单例的ConcurrentCompositeConfiguration对象就创建完成了。

03

基于接口的配置管理

(1)接着我们继续分析initEurekaServerContext()方法,初始化服务的上下文。这个方法超级长,我们要一点点看,并且在这个方法中我们会看到很多和eureka服务端,客户端相关的配置类的创建和初始化。

代码语言:javascript
复制
  //第一步 初始化eureka-server配置
        EurekaServerConfig eurekaServerConfig = new DefaultEurekaServerConfig();

可以看到我们先是从上文中构建的配置对象去获取当前的环境,默认值,test,并且重新又设置了一个属性值。而其中的EUREKA_PROPS_FILE其实就是eureka-server。

代码语言:javascript
复制
 ConfigurationManager
 .loadCascadedPropertiesFromResources(eurekaPropsFile);

而这行代码就是去读取eureka-server.properties文件中的配置,并且将所有的key-value对都加载进ConcurrentMapConfiguration对象中的map中。

技术亮点:这里的代码我截图出来是因为发现它采用了根据key hash之后分段加锁的机制,这样大大提高了锁并发的能力,优秀。

总结:到这里就把eureka-server.properties文件中所有的属性都加载进了配置对象中。我们看项目中的这个配置文件,是空的。

(2)我们可以看到EurekaServerConfig是一个接口,并且可以看到里面有大量的get方法,都是各个属性值的获取方法。而DefaultEurekaServerConfig是EurekaServerConfig的子类,在实现的子类中可以获取到所有配置项的值,并且每个配置项都提供了默认值。

在他初始化的时候有一个成员变量也进行了初始化赋值。

代码语言:javascript
复制
private static final DynamicPropertyFactory configInstance =
 com.netflix.config.DynamicPropertyFactory.getInstance();

这个configInstance对象也是单例创建的,他的配置就来自上文中的config对象,如果他不能获取到值,就会使用DefaultEurekaServerConfig提供的默认值。

总结:eureka的配置管理是如何做的呢?

我们常见的一个类中写所有配置项的常量,然后把所有配置项通过properties加载进内存,然后根据常量作为key,获取value。

eureka并没有采用这种方式,eureka采用了基于接口做配置管理,将所有的配置项属性都以getXXX的方式对外暴露出去,然后实现类,通过数据源获取值以及提供默认配置值的方式提供配置项的值。

这样子做对于我们使用者来说更简单易用,而且也是面向对象的,更透明,我们只需要根据key的getXXX方法去调用就可以了。而采用常量的方式来处理的话,庞大的常量可能会搞混,而且修改起来也比较麻烦。

最后我用一张图总结一下今天阅读的源码部分。

最后,谢谢大家观看,文中若有错误,欢迎指正。文中也有很多源码部分没有展开,欢迎各位朋友留言讨论。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 逆熵架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档