20

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

 4 years ago
source link: http://www.cnblogs.com/wang-meng/p/12106321.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

在源码分析三、四都有提及到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());

流程图

NjiqEvz.png!web

申明

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

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

Q77ZVzY.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK