Spring Cloud Eureka 全解 (6) - 一些熱門QA

本文基於SpringCloud-Dalston.SR5spring

Eureka服務實例啓動時,是否會馬上向EurekaServer註冊?

是的,馬上會。緩存

EurekaClient在每次實例狀態發生改變時,有一個Listener:網絡

statusChangeListener = new ApplicationInfoManager.StatusChangeListener() {
    @Override
    public String getId() {
        return "statusChangeListener";
    }

    @Override
    public void notify(StatusChangeEvent statusChangeEvent) {
        if (InstanceStatus.DOWN == statusChangeEvent.getStatus() ||
                InstanceStatus.DOWN == statusChangeEvent.getPreviousStatus()) {
            // log at warn level if DOWN was involved
            logger.warn("Saw local status change event {}", statusChangeEvent);
        } else {
            logger.info("Saw local status change event {}", statusChangeEvent);
        }
//這個會觸發調用register接口將實例信息註冊上去
        instanceInfoReplicator.onDemandUpdate();
    }
};

實例初始化完畢時,會發送一個狀態爲UP的事件,觸發這個Listener(狀態從STARTING變成UP ):app

@Override
public void register(EurekaRegistration reg) {
   maybeInitializeClient(reg);

   if (log.isInfoEnabled()) {
      log.info("Registering application " + reg.getInstanceConfig().getAppname()
            + " with eureka with status "
            + reg.getInstanceConfig().getInitialStatus());
   }

   reg.getApplicationInfoManager()
         .setInstanceStatus(reg.getInstanceConfig().getInitialStatus());

   if (reg.getHealthCheckHandler() != null) {
      reg.getEurekaClient().registerHealthCheck(reg.getHealthCheckHandler());
   }
}

那麼,官網這兩個配置有啥用: image 其實這個Initially是另一個邏輯,就是在應用啓動40s後,檢查實例信息是否老舊,或者第一次註冊是否失敗,若是失敗,就再次註冊。以後每隔30s執行一次這個任務異步

EurekaServer集羣內部信息如何同步?

首先,EurekaClient會選擇eureka.client.service-url.defaultZone配置的第一個EurekaServer,以後若是和這個EurekaServer沒有網絡問題,就會一直用這個。 在EurekaClient向EurekaServer發送註冊,下線,心跳,狀態改變等一切事件時,這些會在EurekaServer上面同步到集羣(EurekaServer集羣配置就是eureka.client.service-url.defaultZone,集羣內每一個EurekaServer)的全部Server上ide

image

這樣的機制有沒有問題?微服務

  1. 這個同步到其餘EurekaServer與本次EurekaClient請求是不是同步的? 不是同步的,例如註冊到EurekaServerA,EurekaServerA將註冊請求同步到EurekaServerB與當前註冊請求是異步的
  2. 某次異步同步請求失敗如何補償? 例如服務實例A註冊到EurekaServerA,可是同步到EurekaServerB失敗。這時EurekaServerB就沒有這個實例,在下次A心跳時,EurekaServerA同步心跳請求到EurekaServerB時,會返回404,觸發從新註冊 推論: 爲了減小和均勻EurekaServer壓力和訪問便利,咱們對於每一個微服務的不一樣實例,配置Eureka集羣都要寫的順序不同,和本身網段同樣的寫的靠前

網絡抖動時,致使訪問到另外一個Eureka,重啓才能恢復。。。url

服務實例怎麼過時?

經過EurekaServer內部定時檢查過時實例任務,掃描Registry裏面過時的實例並刪除,而且使對應的ReadWriteMap緩存失效 注意,ReadOnlyMap裏面的並不會馬上失效,而是經過下一個只讀緩存刷新從ReadWriteMap刷到ReadOnlyMap感知變化。由於EurekaClient獲取實例信息只從ReadOnlyMap讀取,因此EurekaClient感知變化也會有這個延遲設計

image

爲什麼EurekaServer掛了,客戶端依然能夠調通?

SpringCloud環境下,EurekaClient有緩存,Ribbon對於調用的服務列表也有緩存,因此能夠繼續調用,但不會更新服務與實例列表了。 根據Eureka的self-preservation的設計思路,能夠理解這種設計也是符合Eureka初衷的(CAP中的A)code

image

相關文章
相關標籤/搜索