V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yuexiahandao
V2EX  ›  Java

关于 Eureka 启动的说明

  •  1
     
  •   yuexiahandao · 2017-09-20 21:54:37 +08:00 · 4303 次点击
    这是一个创建于 2606 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Eureka 使用说明

    一般 Eureka 在使用的时候大家都是使用 Spring Boot 的 start 方式来实现,这种方式比较简单易用,但是隐藏了很多的实现细节,其实未必是很好的事情。那么 Eureka 是如何实现的呢?下面我们来探究一下。

    Eureka Server 之启动分析

    初始化

    下载完 eureka 的源码之后,我们来看一下结构,其中有一个子模块 eureka-server,这个模块是一个 web 项目。我们看一下 web.xml ,发现里面配置了一个 Listener,这个 Listener 是 Eureka core 里的 EurekaBootStrap。这个类就是 eureka Server 能工具的启动类,居然是通过 tomcat 的 Listener 机制实现的,如果是 Jetty 是不是该设置 handler ?不了解 jetty,所以不多说了。我们来看一下这个类都做了哪些事。

    这个类的实现其实比较简单,主要方法在 contextInitialized 方法中,首先调用 initEurekaEnvironment 来初始化 Eureka 环境。这个方法里面使用了 archaius-core 里面的 ConfigurationManager 类,这个类就是专门用来加载相应的配置的。

    ConfigurationManager 这个类使用了 Apache Commons Configuration 这个 jar 包来进行系统级统一配置的管理。我们可以先查看 getConfigInstance 是如何生成 AbstractConfiguration, 里面使用了 ConcurrentCompositeConfiguration,这个类会组合各种 Configuration,当你查找对应的属性的时候,它会逐个 Configuration 地查找,直到查到你要的属性。这个是 archaius-core 里面的具体实现,我们的配置也是提供了类似的定制化的初始数据配置,但是我们在使用 eureka 系统的时候基本上没有配置什么初始化属性,所以都是使用的默认属性。当然如果想实现自己的定制初始化配置,可以使用 archaius-core 里面给我们的配置方式进行配置。initEurekaEnvironment 中需要读取 eureka.datacenter 和 archaius.deployment.environment 来配置。默认分别是 default 和 test。

    OK,以上就是设置 Environment 的过程,这其实是因为使用了 archaius 的缘故,其实也没啥。下面的 initEurekaServerContext 才是重头戏。它首先新建了 DefaultEurekaServerConfig,然后使用 Xstream 这个第三方库,实例化了 JSON 和 XML 的解析器。然后初始化自己的 JSONXstream 和 XmlXStream,这两个类都是继承 XStream 的,里面主要是利用了 XStream 提供的 Converts 外接自定义的方式进行实现的,在这两个类中向 XStream 注册了很多在 Converts 类中定义的各种 Converts,然后触发 XStream 的注解处理器,当然这个注解的处理器就是上面我们定义的那些 Converts,中间是通过注解的类进行的沟通,而且每种注解的意义都是预设的,这个以后研究说明,这里就简单介绍一下;我们可以看一下 XMLXStream 类的构造方法就明白了。

    public XmlXStream() {
            super(new DomDriver(null, initializeNameCoder()));
    
            // 注册自己的 Converters
            registerConverter(new Converters.ApplicationConverter());
            registerConverter(new Converters.ApplicationsConverter());
            registerConverter(new Converters.DataCenterInfoConverter());
            registerConverter(new Converters.InstanceInfoConverter());
            registerConverter(new Converters.LeaseInfoConverter());
            registerConverter(new Converters.MetadataConverter());
            setMode(XStream.NO_REFERENCES);
            // 触发注解实现,利用上面注册的 Converts 处理下面的注解。
            processAnnotations(new Class[]{InstanceInfo.class, Application.class, Applications.class});
    }
    

    接着创建 ServerCodec 实例,ServerCodec 是封装了,JSON 和 XML 解析的实现,类内部聚合了 CodecWrapper,CodecWrapper 是用来封装具体的 JSON 和 XML 的解析。这个可以看到具体的实现:

    public class DefaultServerCodecs implements ServerCodecs {
    
        protected final CodecWrapper fullJsonCodec;
        protected final CodecWrapper compactJsonCodec;
    
        protected final CodecWrapper fullXmlCodec;
        protected final CodecWrapper compactXmlCodec;
        ......
    }
    

    关于 CodecWrapper 其实就是封装统一的 decode 和 encode 函数,这个可以自行去看它的继承机构,具体的实现我们也不用去探究了。主要是利用了 XStream 这个包里面的工具。

    我们可以看一下 EurekaServerConfig:Build 内部类,我们可以发现,JSON 和 XML 的解析实现,我们是可以在系统配置来指定的。

    /**
     * 原来在 EurekaServerConfig 中,我们可以指定 JSON 和 XML 的解析类
     * @param config
     * @return
    */
    public Builder withEurekaServerConfig(EurekaServerConfig config) {
    	fullJsonCodec = CodecWrappers.getCodec(config.getJsonCodecName());
    	fullXmlCodec = CodecWrappers.getCodec(config.getXmlCodecName());
    	return this;
    }
    

    未完待续

    第 1 条附言  ·  2017-09-21 17:50:23 +08:00
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   942 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 20:43 · PVG 04:43 · LAX 12:43 · JFK 15:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.