Eureka 学习笔记(1)

一 、contextInitialized()

eureka-core里面,监听器的执行初始化的方法,是contextInitialized()方法,这个方法就是整个eureka-server启动初始化的一个入口。

java 复制代码
 @Override
    public void contextInitialized(ServletContextEvent event) {
        try {
            initEurekaEnvironment();
            initEurekaServerContext();

            ServletContext sc = event.getServletContext();
            sc.setAttribute(EurekaServerContext.class.getName(), serverContext);
        } catch (Throwable e) {
            logger.error("Cannot bootstrap eureka server :", e);
            throw new RuntimeException("Cannot bootstrap eureka server :", e);
        }
    }

二、initEurekaEnvironment()

我们可以看到第一行代码就是 initEurekaEnvironment();我们点进去可以看到

java 复制代码
  /**
     * Users can override to initialize the environment themselves.
     */
    protected void initEurekaEnvironment() throws Exception {
        logger.info("Setting the eureka configuration..");

        String dataCenter = ConfigurationManager.getConfigInstance().getString(EUREKA_DATACENTER);
        if (dataCenter == null) {
            logger.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);
        }
        String environment = ConfigurationManager.getConfigInstance().getString(EUREKA_ENVIRONMENT);
        if (environment == null) {
            ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST);
            logger.info("Eureka environment value eureka.environment is not set, defaulting to test");
        }
    }

在这里,其实会调用ConfigurationManager.getConfigInstance()方法,这个方法,其实就是初始化ConfigurationManager的实例,也就是一个配置管理器的初始化的这么一个过程。

ConfigurationManager是什么呢?看字面意思都猜的出来,配置管理器,管理eureka自己的所有的配置,读取配置文件里的配置到内存里,供后续的eureka-server运行来使用。

三、创建AbstractConfiguration

我们点击getConfigInstance,可以看到下面的代码

java 复制代码
 public static AbstractConfiguration getConfigInstance() {
        if (instance == null) {
            synchronized (ConfigurationManager.class) {
                if (instance == null) {
                    instance = getConfigInstance(Boolean.getBoolean(DynamicPropertyFactory.DISABLE_DEFAULT_CONFIG));
                }
            }
        }
        return instance;
    }

这是使用double check + volatile创建了一个AbstractConfiguration实例。

单例模式一个经典的作用,就是将配置作为单例,但是一般来说如果你要自己解析配置文件,读取配置的话,一般来说除非你是底层自研的框架。此时你可以设计一个ConfigurationManager,就是一个配置管理器,一般这个会做成单例的。

接下来我们看下createDefaultConfigInstance()方法。

java 复制代码
private static AbstractConfiguration createDefaultConfigInstance() {
        ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();  
        try {
            DynamicURLConfiguration defaultURLConfig = new DynamicURLConfiguration();
            config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME);
        } catch (Throwable e) {
            logger.warn("Failed to create default dynamic configuration", e);
        }
        if (!Boolean.getBoolean(DISABLE_DEFAULT_SYS_CONFIG)) {
            SystemConfiguration sysConfig = new SystemConfiguration();
            config.addConfiguration(sysConfig, SYS_CONFIG_NAME);
        }
        if (!Boolean.getBoolean(DISABLE_DEFAULT_ENV_CONFIG)) {
            EnvironmentConfiguration envConfig = new EnvironmentConfiguration();
            config.addConfiguration(envConfig, ENV_CONFIG_NAME);
        }
        ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration();
        config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES);
        config.setContainerConfigurationIndex(config.getIndexOfConfiguration(appOverrideConfig));
        return config;
    }

1)创建一个ConcurrentCompositeConfiguration实例,这个东西,其实就是代表了所谓的配置,包括了eureka需要的所有的配置。在初始化这个实例的时候,调用了clear()方法

java 复制代码
 public ConcurrentCompositeConfiguration()
    {
        clear();
    }

2)我们点击clear可以看到

java 复制代码
  @Override
    public final void clear()
    {
        fireEvent(EVENT_CLEAR, null, null, true);
        configList.clear();
        namedConfigurations.clear();
        // recreate the in memory configuration
        containerConfiguration = new ConcurrentMapConfiguration();
        containerConfiguration.setThrowExceptionOnMissing(isThrowExceptionOnMissing());
        containerConfiguration.setListDelimiter(getListDelimiter());
        containerConfiguration.setDelimiterParsingDisabled(isDelimiterParsingDisabled());
        containerConfiguration.addConfigurationListener(eventPropagater);
        configList.add(containerConfiguration);
        
        overrideProperties = new ConcurrentMapConfiguration();
        overrideProperties.setThrowExceptionOnMissing(isThrowExceptionOnMissing());
        overrideProperties.setListDelimiter(getListDelimiter());
        overrideProperties.setDelimiterParsingDisabled(isDelimiterParsingDisabled());
        overrideProperties.addConfigurationListener(eventPropagater);
        
        fireEvent(EVENT_CLEAR, null, null, false);
        containerConfigurationChanged = false;
        invalidate();
    }

fireEvent()发布了一个事件(EVENT_CLEAR),fireEvent()这个方法其实是父类的方法,牵扯比较复杂的另外一个项目(ConfigurationManager本身不是属于eureka的源码,是属于netflix config项目的源码,暂不学习。

总的来说,就是往ConcurrentCompositeConfiguration实例加入了一堆别的config,然后搞完了以后,就直接返回了这个实例,就是作为所谓的那个配置的单例

四、初始化数据中心的配置,如果没有配置的话,就是DEFAULT data center

java 复制代码
 String dataCenter = ConfigurationManager.getConfigInstance().getString(EUREKA_DATACENTER);
        if (dataCenter == null) {
            logger.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);

五、初始化eurueka运行的环境,如果你没有配置的话,默认就给你设置为test环境

java 复制代码
String environment = ConfigurationManager.getConfigInstance().getString(EUREKA_ENVIRONMENT);
        if (environment == null) {
            ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST);
            logger.info("Eureka environment value eureka.environment is not set, defaulting to test");
        }

六、initEurekaEnvironment的初始化环境的逻辑,就结束了

七、流程图

参考:Eureka 学习笔记(六)Eureka初始化环境

相关推荐
HSunR2 分钟前
概率论 期末 笔记
笔记·概率论
红色的山茶花13 分钟前
YOLOv9-0.1部分代码阅读笔记-loss_tal.py
笔记·深度学习·yolo
dessler16 分钟前
Docker-如何启动docker
运维·docker·云原生·容器·eureka
biter00881 小时前
opencv(15) OpenCV背景减除器(Background Subtractors)学习
人工智能·opencv·学习
车轮滚滚__1 小时前
uniapp对接unipush 1.0 ios/android
笔记
Code哈哈笑2 小时前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
QQ同步助手3 小时前
如何正确使用人工智能:开启智慧学习与创新之旅
人工智能·学习·百度
流浪的小新3 小时前
【AI】人工智能、LLM学习资源汇总
人工智能·学习
A懿轩A4 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
云边有个稻草人4 小时前
【优选算法】—复写零(双指针算法)
笔记·算法·双指针算法