• 【一起学源码-微服务】Nexflix Eureka 源码五:EurekaClient启动要经历哪些艰难险阻?


    前言

    在源码分析三、四都有提及到EurekaClient启动的一些过程。因为EurekaServer在集群模式下 自己本身就是一个client,所以之前初始化eurekaServerContext就有涉及到eurekaClient的初始化。

    我们也看了EurekaClient(DiscoveryClient)初始化的过程,繁杂的启动过程让人眼花缭乱,这篇文章就专门来唠唠 里面经历的一些艰难险阻。这也会是后面client注册的一个前置文章。

    如若转载 请标明来源:一枝花算不算浪漫

    从ExampleEurekaClient开始说起

    在第一讲我们就说过,eureka项目有一个examples模块的,现在看一下其中的EurekaClientExample对象:

    public class ExampleEurekaClient {
    
        private static ApplicationInfoManager applicationInfoManager;
        private static EurekaClient eurekaClient;
    
        private static synchronized ApplicationInfoManager initializeApplicationInfoManager(EurekaInstanceConfig instanceConfig) {
            if (applicationInfoManager == null) {
                InstanceInfo instanceInfo = new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get();
                applicationInfoManager = new ApplicationInfoManager(instanceConfig, instanceInfo);
            }
    
            return applicationInfoManager;
        }
    
        private static synchronized EurekaClient initializeEurekaClient(ApplicationInfoManager applicationInfoManager, EurekaClientConfig clientConfig) {
            if (eurekaClient == null) {
                eurekaClient = new DiscoveryClient(applicationInfoManager, clientConfig);
            }
    
            return eurekaClient;
        }
    
    
        public void sendRequestToServiceUsingEureka(EurekaClient eurekaClient) {
            // initialize the client
            // this is the vip address for the example service to talk to as defined in conf/sample-eureka-service.properties
            String vipAddress = "sampleservice.mydomain.net";
    
            InstanceInfo nextServerInfo = null;
            try {
                nextServerInfo = eurekaClient.getNextServerFromEureka(vipAddress, false);
            } catch (Exception e) {
                System.err.println("Cannot get an instance of example service to talk to from eureka");
                System.exit(-1);
            }
    
            System.out.println("Found an instance of example service to talk to from eureka: "
                    + nextServerInfo.getVIPAddress() + ":" + nextServerInfo.getPort());
    
            System.out.println("healthCheckUrl: " + nextServerInfo.getHealthCheckUrl());
            System.out.println("override: " + nextServerInfo.getOverriddenStatus());
    
            Socket s = new Socket();
            int serverPort = nextServerInfo.getPort();
            try {
                s.connect(new InetSocketAddress(nextServerInfo.getHostName(), serverPort));
            } catch (IOException e) {
                System.err.println("Could not connect to the server :"
                        + nextServerInfo.getHostName() + " at port " + serverPort);
            } catch (Exception e) {
                System.err.println("Could not connect to the server :"
                        + nextServerInfo.getHostName() + " at port " + serverPort + "due to Exception " + e);
            }
            try {
                String request = "FOO " + new Date();
                System.out.println("Connected to server. Sending a sample request: " + request);
    
                PrintStream out = new PrintStream(s.getOutputStream());
                out.println(request);
    
                System.out.println("Waiting for server response..");
                BufferedReader rd = new BufferedReader(new InputStreamReader(s.getInputStream()));
                String str = rd.readLine();
                if (str != null) {
                    System.out.println("Received response from server: " + str);
                    System.out.println("Exiting the client. Demo over..");
                }
                rd.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws Exception{
    		injectEurekaConfiguration();
            ExampleEurekaClient sampleClient = new ExampleEurekaClient();
    
    		// MyDataCenterInstanceConfig 就是加载eureka-client.properties配置信息,形成一个服务实例的配置EurekaInstanceConfig
    		// 基于EurekaClient配置,构造了一个服务实例(InstanceInfo)
    		// 基于eureka client配置和服务实例,构造了一个服务实例管理器(ApplicationInfoManager)
    		// 读取eureka-client.properties配置文件,形成了一个eureka client的配置,接口对外提供eureka client的配置项的读取
    		// 基于eureka client的配置,和服务实例管理器,来构造了一个EurekaClient(DiscoveryClient
    		// ),保存了一些配置,处理服务的注册和注册表的抓取,启动了几个线程池,启动了网络通信组件,启动了一些调度任务,注册了监控项
            ApplicationInfoManager applicationInfoManager = initializeApplicationInfoManager(new MyDataCenterInstanceConfig());
            EurekaClient client = initializeEurekaClient(applicationInfoManager, new DefaultEurekaClientConfig());
    
            // use the client
            sampleClient.sendRequestToServiceUsingEureka(client);
    
    
            // shutdown the client
            eurekaClient.shutdown();
        }
    
    	/**
    	 * This will be read by server internal discovery client. We need to salience it.
    	 */
    	private static void injectEurekaConfiguration() throws UnknownHostException {
    		String myHostName = InetAddress.getLocalHost().getHostName();
    		String myServiceUrl = "http://" + myHostName + ":8080/v2/";
    
    		System.setProperty("eureka.region", "default");
    		System.setProperty("eureka.name", "eureka");
    		System.setProperty("eureka.vipAddress", "eureka.mydomain.net");
    		System.setProperty("eureka.port", "8080");
    		System.setProperty("eureka.preferSameZone", "false");
    		System.setProperty("eureka.shouldUseDns", "false");
    		System.setProperty("eureka.shouldFetchRegistry", "true");
    		System.setProperty("eureka.serviceUrl.defaultZone", myServiceUrl);
    		System.setProperty("eureka.serviceUrl.default.defaultZone", myServiceUrl);
    		System.setProperty("eureka.awsAccessId", "fake_aws_access_id");
    		System.setProperty("eureka.awsSecretKey", "fake_aws_secret_key");
    		System.setProperty("eureka.numberRegistrySyncRetries", "0");
    	}
    }
    

    这里我们从main函数开始看起:

    1. 注入eureka配置信息:injectEurekaConfiguration();
    2. 读取eureka-client.properties配置文件,形成一个服务器实例的配置,基于接口对外提供实例的配置项读取
      这里就是涉及到我么你之前讲解的DynamicPropertyFactoryConfigurationManager,这里可以查看new MyDataCenterInstanceConfig()然后一步步往后跟。
    3. 基于服务实例的配置,构造了一个服务实例(InstanceInfo)。initializeApplicationInfoManager中会构建InstanceInfo信息
    4. 基于服务实例的配置和服务实例,初始化服务实例管理器(ApplicationInfoManager)
    5. 基于eureka client配置,和服务实例管理器,来构造了一个EurekaClient(DiscoveryClient),保存了一些配置,处理服务的注册和注册表的抓取,启动了几个线程池,启动了网络通信组件,启动了一些调度任务,注册了监控项
      具体可查看 EurekaClient client = initializeEurekaClient(applicationInfoManager, new DefaultEurekaClientConfig());

    流程图

    02_Eureka_Client启动流程图.png

    申明

    本文章首发自本人博客:https://www.cnblogs.com/wang-meng 和公众号:壹枝花算不算浪漫,如若转载请标明来源!

    感兴趣的小伙伴可关注个人公众号:壹枝花算不算浪漫

    22.jpg

  • 相关阅读:
    xcodebuild changed some of the values
    ar和nm命令的使用(转载)
    POJ 3678 Katu Puzzle (2SAT)
    ZOJ 3664 Split the Rectangle 第37届ACM/ICPC长春赛区现场赛 J 题(模拟建树,暴力 求LCA)
    HDU 4115 Eliminate the Conflict (2SAT)
    ZOJ 3665 Yukari's Birthday 第37届ACM/ICPC长春赛区现场赛K题 (水题,枚举,二分)
    ZOJ 3662 Math Magic 第37届ACM/ICPC长春赛区H题(DP)
    【原创】2012ACM长春赛区现场赛总结
    ZOJ 3656 Bit Magic 第37届ACM/ICPC长春赛区现场赛B题 (2SAT)
    ZOJ 3657 The Little Girl who Picks Mushrooms 第37届ACM/ICPC长春赛区现场赛C题(水题)
  • 原文地址:https://www.cnblogs.com/wang-meng/p/12106321.html
Copyright © 2020-2023  润新知