【一塊兒學源碼-微服務】Nexflix Eureka 源碼五:EurekaClient啓動要經歷哪些艱難險阻?

前言

在源碼分析3、四都有說起到EurekaClient啓動的一些過程。由於EurekaServer在集羣模式下 本身自己就是一個client,因此以前初始化eurekaServerContext就有涉及到eurekaClient的初始化。java

咱們也看了EurekaClient(DiscoveryClient)初始化的過程,繁雜的啓動過程讓人眼花繚亂,這篇文章就專門來嘮嘮 裏面經歷的一些艱難險阻。這也會是後面client註冊的一個前置文章。服務器

如若轉載 請標明來源:一枝花算不算浪漫網絡

從ExampleEurekaClient開始提及

在第一講咱們就說過,eureka項目有一個examples模塊的,如今看一下其中的EurekaClientExample對象:app

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函數開始看起:dom

  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 和公衆號:壹枝花算不算浪漫,如若轉載請標明來源!ide

感興趣的小夥伴可關注我的公衆號:壹枝花算不算浪漫函數

22.jpg

相關文章
相關標籤/搜索