<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【Spring Cloud】Eureka-Client 源碼解讀

          共 4475字,需瀏覽 9分鐘

           ·

          2021-06-02 09:12

          一、前言

          看源碼:抓大放小,先主流程,再細(xì)枝末節(jié)。

          用技巧連蒙帶猜:

          1. 看方法名(英文名)

          2. 看注釋

          搭建環(huán)境:

          // 定位:eureka-examples 模塊下
          // 修改 ExampleEurekaClient.java

          // 1. 增加一個(gè)方法,用于初始化環(huán)境變量,方便調(diào)試
          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", "false");
          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");
          }


          // 2. 在 main 方法添加
          public static void main(String[] args) throws UnknownHostException {

          // 添加如下這行
          injectEurekaConfiguration();
          ... ...
          }
          復(fù)制代碼



          二、從源碼中學(xué)到了什么



          三、直接懟源碼

          (1)eureka-client 如何啟動(dòng)(初始化)?

          代碼如下:

          // 定位:com.netflix.eureka.ExampleEurekaClient.java
          public static void main(String[] args) throws UnknownHostException {
          // 1. 初始化 eureka 環(huán)境變量
          injectEurekaConfiguration();
          // 2. 創(chuàng)建 eureka 服務(wù)
          ExampleEurekaClient sampleClient = new ExampleEurekaClient();
          // 3. 創(chuàng)建服務(wù)實(shí)例管理器
          ApplicationInfoManager applicationInfoManager =
          initializeApplicationInfoManager(new MyDataCenterInstanceConfig());
          // 4. 創(chuàng)建 eureka-client
          EurekaClient client =
          initializeEurekaClient(applicationInfoManager, new DefaultEurekaClientConfig());

          ... ...
          }
          復(fù)制代碼

          過(guò)程如下:

          1. 初始化 eureka 環(huán)境變量

          2. 創(chuàng)建 eureka 服務(wù),會(huì)有一個(gè) eureka-client

          3. 創(chuàng)建服務(wù)實(shí)例管理器

            ApplicationInfoManager applicationInfoManager = initializeApplicationInfoManager(new MyDataCenterInstanceConfig());
            復(fù)制代碼
            1. 構(gòu)建服務(wù)實(shí)例(InstanceInfo

            2. 構(gòu)建服務(wù)實(shí)例管理器(ApplicationInfoManager

          4. 創(chuàng)建 eureka-client(通過(guò)構(gòu)造 DiscoveryClient

            • 處理配置

            • 服務(wù)的注冊(cè)和注冊(cè)表的抓取(初始化網(wǎng)絡(luò)通信組件)

            • 創(chuàng)建幾個(gè)線(xiàn)程池,啟動(dòng)調(diào)度任務(wù)

            • 注冊(cè)監(jiān)控項(xiàng)



          (2)eureka-client 如何服務(wù)注冊(cè)的?

          針對(duì)注冊(cè),提出問(wèn)題:

          1. 什么時(shí)候進(jìn)行服務(wù)注冊(cè)?初始化 eureka-client 時(shí)候

          eureka-client 的服務(wù)注冊(cè),是在 InstanceInfoReplicator 中完成的。

          1. 服務(wù)注冊(cè)做哪些操作?主要發(fā)送 HTTP 請(qǐng)求

          針對(duì)這個(gè)兩個(gè)問(wèn)題,來(lái)看下源碼。雖然這部分的源碼寫(xiě)的不好,但也可以學(xué)習(xí)了解下他人的思路。

          這部分源碼比較難找,實(shí)際是在創(chuàng)建 DiscoveryClientinitScheduledTasks()(初始化調(diào)度任務(wù))

          // 定位:com.netflix.discovery.DiscoveryClient.java
          private void initScheduledTasks() {
          // InstanceRegisterManager:實(shí)例注冊(cè)管理器,專(zhuān)門(mén)來(lái)管理實(shí)例注冊(cè)
          // 傳參:默認(rèn) 40秒
          instanceInfoReplicator.start(...);
          }
          復(fù)制代碼
          1. 啟動(dòng)實(shí)例注冊(cè)管理器(InstanceRegisterManager

          // 定位:com.netflix.discovery.InstanceInfoReplicator.java
          public void start(int initialDelayMs) {
          // 原子操作
          if (started.compareAndSet(false, true)) {
          // 1. 先設(shè)置 isDirty = true
          instanceInfo.setIsDirty();
          // 2. 調(diào)度器執(zhí)行,將自身傳入,并且調(diào)度時(shí)間默認(rèn)為 40 秒
          // 所以會(huì)執(zhí)行 InstanceInfoReplicator.run() 方法
          Future next = scheduler.schedule(this, initialDelayMs, TimeUnit.SECONDS);
          scheduledPeriodicRef.set(next);
          }
          }
          復(fù)制代碼
          1. 執(zhí)行 InstanceInfoReplicator.run()

          // 定位:com.netflix.discovery.InstanceInfoReplicator.java
          // 會(huì)發(fā)現(xiàn):class InstanceInfoReplicator implements Runnable,是可創(chuàng)建線(xiàn)程的。
          public void run() {
          try {
          // 1. 刷新了服務(wù)實(shí)例的信息,拿到服務(wù)的狀態(tài)
          discoveryClient.refreshInstanceInfo();
          Long dirtyTimestamp = instanceInfo.isDirtyWithTime();
          if (dirtyTimestamp != null) {
          // 2. 注冊(cè):因?yàn)橹耙呀?jīng)設(shè)置 isDirty = true,所以下面直接注冊(cè)
          discoveryClient.register();
          // 3. 設(shè)置 isDirty = false
          instanceInfo.unsetIsDirty(dirtyTimestamp);
          }
          } catch (Throwable t) {
          logger.warn("There was a problem with the instance info replicator", t);
          } finally {
          // 4. 再次把自己丟進(jìn)調(diào)度線(xiàn)程中
          Future next =
          scheduler.schedule(this, replicationIntervalSeconds, TimeUnit.SECONDS);
          scheduledPeriodicRef.set(next);
          }
          }
          復(fù)制代碼
          1. 重要:注冊(cè) discoveryClient.register();

          // 定位:com.netflix.discovery.DiscoveryClient.java
          boolean register() throws Throwable {
          EurekaHttpResponse<Void> httpResponse;
          try {
          // 發(fā)送 HTTP 請(qǐng)求
          httpResponse = eurekaTransport.registrationClient.register(instanceInfo);
          ... ...
          }
          ... ...
          return httpResponse.getStatusCode() == 204;
          }


          作者:卷卷啊
          鏈接:https://juejin.cn/post/6968080788868825118
          來(lái)源:掘金
          著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。


          瀏覽 38
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  jiZZJIZZ成熟丰满少妇 | 影音先锋亚洲无码在线观看 | 亚洲无免费码在线 | 3级片免费网站免费播放无码久久 | 国产美女丝袜足交视频 |