1.eureka源码分析:eureka server的启动入口

 开局来一张eureka server的启动流程图:

 首先,github上下载eureka源码,找到eureka-server这个module,找到web.xml,对于Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。

  <!-- listener:项目启动入口,入口类:EurekaBootStrap-->
  <listener>
    <listener-class>com.netflix.eureka.EurekaBootStrap</listener-class>
  </listener>
那么整个项目的启动类就是com.netflix.eureka.EurekaBootStrap这个类。来看类定义:
public class EurekaBootStrap implements ServletContextListener {

实现该接口,就要实现contextInitialized这个方法。

	/**
	 ** Notification that the web application initialization
	 ** process is starting.
	 ** All ServletContextListeners are notified of context
	 ** initialization before any filter or servlet in the web
	 ** application is initialized.
	 */

    public void contextInitialized ( ServletContextEvent sce );

其实现方法是:
 

@Override
    public void contextInitialized(ServletContextEvent event) {
        try {
            //初始化环境
            initEurekaEnvironment();
            //启动eureka server
            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();一个是initEurekaServerContext();

首先来看第一个initEurekaEnvironment()方法:

    protected void initEurekaEnvironment() throws Exception {
        logger.info("Setting the eureka configuration..");
        //从ConfigurationManager拿到一个配置管理器实例
        //eureka.datacenter:从eureka-client.properties中读取,默认为空
        String dataCenter = ConfigurationManager.getConfigInstance().getString(EUREKA_DATACENTER);
        if (dataCenter == null) {
            //这里是null,dataCenter被设为default,datacenter应该是在多个数据中心用来区分环境的
            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);
        }
        //这里的EUREKA_ENVIRONMENT用来觉定读取哪个配置文件,将会拼接到配置文件名称上,拼接后的形式是:
        // eureka-server-<eureka.environment>.properties
        //EUREKA_ENVIRONMENT配置:eureka.environment
        String environment = ConfigurationManager.getConfigInstance().getString(EUREKA_ENVIRONMENT);
        if (environment == null) {
            //ARCHAIUS_DEPLOYMENT_ENVIRONMENT:archaius.deployment.environment,默认设置为TEST:test
            ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST);
            logger.info("Eureka environment value eureka.environment is not set, defaulting to test");
        }
    }

重点看第二个方法initEurekaServerContext():

   /**
     * init hook for server context. Override for custom logic.
     */
    protected void initEurekaServerContext() throws Exception {
        //通过配置文件拿配置保存在内存中
        EurekaServerConfig eurekaServerConfig = new DefaultEurekaServerConfig();

        // For backward compatibility
        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());
        ServerCodecs serverCodecs = new DefaultServerCodecs(eurekaServerConfig);
        ApplicationInfoManager applicationInfoManager = null;
        //初始化ApplicationInfoManager 初始化eurekaclient,这里显然会走if语句
        if (eurekaClient == null) {
            //不是云环境,走MyDataCenterInstanceConfig,通过eureka-client.properties读取配置
            EurekaInstanceConfig instanceConfig = isCloud(ConfigurationManager.getDeploymentContext())
                    ? new CloudInstanceConfig()
                    : new MyDataCenterInstanceConfig();
            //new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get() 返回 InstanceInfo
            //基于配置和instanceInfo作为服务实例的一个管理器
            applicationInfoManager = new ApplicationInfoManager(
                    instanceConfig, new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get());
            //该实例代表了读取的eureka-client.properties配置文件
            EurekaClientConfig eurekaClientConfig = new DefaultEurekaClientConfig();
            //构建eurekaClient
            eurekaClient = new DiscoveryClient(applicationInfoManager, eurekaClientConfig);
        } else {
            applicationInfoManager = eurekaClient.getApplicationInfoManager();
        }
        //初始化PeerAwareInstanceRegistry
        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 {
//            走这里,创建PeerAwareInstanceRegistryImpl:集群中的一个server实例
            //也就是当前的这个server实例
            registry = new PeerAwareInstanceRegistryImpl(
                    eurekaServerConfig,
                    eurekaClient.getEurekaClientConfig(),
                    serverCodecs,
                    eurekaClient
            );
        }
//        代表了整个eureka server的集群,创建了peerEurekaNodes
        PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(
                registry,
                eurekaServerConfig,
                eurekaClient.getEurekaClientConfig(),
                serverCodecs,
                applicationInfoManager
        );
        //将构造好的对象用来创建EurekaServerContext,context用于在整个系统运行期间
//        可以通过context获取变量
        serverContext = new DefaultEurekaServerContext(
                eurekaServerConfig,
                serverCodecs,
                registry,
                peerEurekaNodes,
                applicationInfoManager
        );

        EurekaServerContextHolder.initialize(serverContext);

        serverContext.initialize();
        logger.info("Initialized server context");

        // Copy registry from neighboring eureka node
        //从相邻的一个server拷贝注册表信息
        int registryCount = registry.syncUp();
        registry.openForTraffic(applicationInfoManager, registryCount);

        // Register all monitoring statistics.
        EurekaMonitors.registerAllStats();
    }

这个方法是启动时最重要的方法了,这个方法执行完成,eureka server就启动完成了,后面文章将详细分析启动具体过程。

总结一下:

web.xml文件

    ->Listener类EurekaBootStrap

         ->contextInitialized方法

            ->initEurekaEnvironment()

            ->initEurekaServerContext();

后面重点分析initEurekaServerContext();方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值