07_吃透eureka源码之梳理server整个启动的流程

本文详细梳理了Eureka Server的初始化流程,从web.xml配置到EurekaServerContext的创建过程,涉及EurekaBootStrap监听器、配置管理、服务实例管理等多个环节。

1,回顾前面写的分析文章

通过前面的写的几篇源码分析的文章,我发现可能对于初学的人员有点难以接受,我还是先把整体的大的流程先给大家总结出来,然后后续我们就根据每个流程在进行细化,这样对大家也有一个比较清晰的认识,对我后面讲解的时候也比较容易理解。

2,eureka server初始化整个流程的梳理

1,web.xml
当eureka.war启动的时候,首先肯定会加载

 <listener>
    <listener-class>com.netflix.eureka.EurekaBootStrap</listener-class>
 </listener>

2,初始化EurekaBootStrap
容器直接调用contextInitialized 方法

public void contextInitialized(ServletContextEvent event){
  ......
}

3,初始化eureka环境

initEurekaEnvironment();
这个方法通过单列的方式初始化eureka的配置
并且环境配置数据通过 ConfigurationManager进行管理

4,初始化eureka的Context
调用initEurekaServerContext()方法,我们进行相关的流程分析

protected void initEurekaServerContext() throws Exception {
        //1,通过接口的方式对外暴露EurekaServer配置,通过方法的方式进行配置获取,并且加载 eureka-server.properties 文件
        EurekaServerConfig eurekaServerConfig = new DefaultEurekaServerConfig();
        //2,注册一个优先级比较高的服务实例的json,xml数据的转换器
        //当中用到了 策略模式,享元模式的方式来优雅的设计
        JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH);
        XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH);
        logger.info("Initializing the eureka client...");
        logger.info(eurekaServerConfig.getJsonCodecName());
        //3,初始化服务器编码器  分别是 json和xml的编码器
        //CodecWrapper接口
        //DefaultServerCodecs 持有4个code解析的对象 设计思想:利用 CodecWrapper 策略实现多个解析codec的方式
        //DefaultServerCodecs内部有一个builder构建器 设计模式是构建器模式来构建 DefaultServerCodecs对象
        //在获取CodecWrapper的实现类时 通过map集合来缓存,这里采用了享元设计模式,缓存codec解析对象,提升性能
        //ServerCodecs serverCodecs = new DefaultServerCodecs(eurekaServerConfig);等同于
        //ServerCodecs serverCodecsBuider =DefaultServerCodecs.builder().build(); 获取的都是默认的编解码实现
        ServerCodecs serverCodecs = new DefaultServerCodecs(eurekaServerConfig);
        ApplicationInfoManager applicationInfoManager = null;
        if (eurekaClient == null) {
            //4,初始化eureka实例配置对象,设置一些默认实例配置数据
            EurekaInstanceConfig instanceConfig = isCloud(ConfigurationManager.getDeploymentContext())
                    ? new CloudInstanceConfig()
                    : new MyDataCenterInstanceConfig();

            //5,生成一个服务实例的提供对象
            //这个是源码的写法 new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get()
            //我只是改造了一下EurekaConfigBasedInstanceInfoProvider 利用构建器模式来构建EurekaConfigBasedInstanceInfoProvider对象,下面变成了我用构建器模式写的,是不是要更加的优雅一些
            EurekaConfigBasedInstanceInfoProvider eurekaConfigBasedInstanceInfoProvider=EurekaConfigBasedInstanceInfoProvider.builder().buidConfig(instanceConfig).build();
            //6,通过instanceConfig,instanceInfo构建了一个ApplicationInfoManager对象,
            //后续进行相关的管理
            applicationInfoManager = new ApplicationInfoManager(
                    instanceConfig, eurekaConfigBasedInstanceInfoProvider.get());



            //7, 初始化EurekaClientConfig配置对象,通过DynamicPropertyFactory来获取数据配置, 面向接口对外提供配置,并且加载eureka-client.properties文件
            EurekaClientConfig eurekaClientConfig = new DefaultEurekaClientConfig();
            //8,构建复杂的eureka客户端初始化过程,后续进行相关的源码分析
            eurekaClient = new DiscoveryClient(applicationInfoManager, eurekaClientConfig);
        } else {
            applicationInfoManager = eurekaClient.getApplicationInfoManager();
        }
        //9,集群服务实例的注册管理组件,维护实例信息数据的管理
        PeerAwareInstanceRegistry registry;
        if (isAws(applicationInfoManager.getInfo())) {
           //这个逻辑不会走
            registry = new AwsInstanceRegistry(
                    eurekaServerConfig,
                    eurekaClient.getEurekaClientConfig(),
                    serverCodecs,
                    eurekaClient
            );
            awsBinder = new AwsBinderDelegate(eurekaServerConfig, eurekaClient.getEurekaClientConfig(), registry, applicationInfoManager);
            awsBinder.start();
        } else {
           //初始化集群服务实例的注册管理组件
            registry = new PeerAwareInstanceRegistryImpl(
                    eurekaServerConfig,
                    eurekaClient.getEurekaClientConfig(),
                    serverCodecs,
                    eurekaClient
            );
        }
		//10,eureka集群管理组件,构造所有配置的集群节点,进行相关的功能处理
        PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(
                registry,
                eurekaServerConfig,
                eurekaClient.getEurekaClientConfig(),
                serverCodecs,
                applicationInfoManager
        );
       //11,初始化EurekaServer的上下文对象
        serverContext = new DefaultEurekaServerContext(
                eurekaServerConfig,
                serverCodecs,
                registry,
                peerEurekaNodes,
                applicationInfoManager
        );
        //12,eureka服务器上下文存放在EurekaServerContextHolder中,方便处理获取serverContext
        EurekaServerContextHolder.initialize(serverContext);

        //13,初始化EurekaServerContext
        serverContext.initialize();
        logger.info("Initialized server context");

        //14,向相邻的集群拷贝注册服务实例对象数据
        int registryCount = registry.syncUp();
        //15,心跳任务启动,进行服务实例注册的处理,后续会进行相关的深入分析
        registry.openForTraffic(applicationInfoManager, registryCount);

        //16,注册所有的监控数据统计
        EurekaMonitors.registerAllStats();
    }

5,把当前的EurekaServerContext存储在容器的上下文对象中

            //得到ServletContext上下文对象
             ServletContext sc = event.getServletContext();
            //把EurekaServerContext放在ServletContext上下文中
            sc.setAttribute(EurekaServerContext.class.getName(), serverContext);
           

通过当前的梳理画图后,我们就非常的清晰,eureka整个server启动都做了哪些事情,后续我们就会在每个点进行相关的细节分析和模式的设计分析,让大家对eureka有比较深入的理解。如果当前的流程对大家还有用的话,请给个赞,原创不易,你的认可就是我的动力,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值