Eureka 服務(wù)注冊(cè)與發(fā)現(xiàn)

core:Java功能增強(qiáng) —— 事件機(jī)制(事件與監(jiān)聽(tīng)器)

Eureka提供了服務(wù)注冊(cè)與發(fā)現(xiàn)的功能,需要提供一個(gè)服務(wù)注冊(cè)中心(我這里是在spring boot項(xiàng)目啟動(dòng)類上使用@EnableEurekaServer泼疑,再配置相關(guān)屬性)切威,然后在我們的應(yīng)用服務(wù)(我這里是spring boot服務(wù))啟動(dòng)類上使用@EnableDiscoveryClient啟用服務(wù)注冊(cè)發(fā)現(xiàn)功能闯狱。那么問(wèn)題來(lái)了洽沟,我們的服務(wù)是怎么注冊(cè)到注冊(cè)中心的呢攘宙?

使用@EnableDiscoveryClient注解后啟動(dòng)服務(wù)丈莺,我們可以發(fā)現(xiàn)控制臺(tái)打出了如下log:


image.png

從圖中可以看出的信息有:1划煮、是在EurekaDiscoveryClientConfiguration中將服務(wù)器注冊(cè)到eureka的。2缔俄、DiscoveryClient類里面應(yīng)該有許多服務(wù)器與eureka之間的通信操作弛秋,如心跳續(xù)約等。3俐载、InstanceInfoReplicator應(yīng)該是一個(gè)線程類蟹略。

既然EurekaDiscoveryClientConfiguration是最開(kāi)始的地方,那就從它看起遏佣。

1挖炬、EurekaDiscoveryClientConfiguration

源碼如下:

@Configuration     //使用該注解來(lái)讓Spring容器發(fā)現(xiàn)并注冊(cè)里面的Bean
@EnableConfigurationProperties
@ConditionalOnClass({EurekaClientConfig.class})
@ConditionalOnProperty(
value = {"eureka.client.enabled"},
matchIfMissing = true
)
public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Ordered {

public void start() {
    if (this.port.get() != 0 && this.instanceConfig.getNonSecurePort() == 0) {
        this.instanceConfig.setNonSecurePort(this.port.get());
    }

    if (!this.running.get() && this.instanceConfig.getNonSecurePort() > 0) {
        this.maybeInitializeClient();
        if (log.isInfoEnabled()) {
            log.info("Registering application " + this.instanceConfig.getAppname() + " with eureka with status " + this.instanceConfig.getInitialStatus());
        }

        this.applicationInfoManager.setInstanceStatus(this.instanceConfig.getInitialStatus());
        if (this.healthCheckHandler != null) {
            this.eurekaClient.registerHealthCheck(this.healthCheckHandler);
        }
        //發(fā)布了一個(gè)注冊(cè)事件,在哪里監(jiān)聽(tīng)的状婶?還是說(shuō)是留給我們開(kāi)發(fā)者用的意敛?
        this.context.publishEvent(new InstanceRegisteredEvent(this, this.instanceConfig));
        this.running.set(true);
    }

}

private void maybeInitializeClient() {
    this.applicationInfoManager.getInfo();
    this.eurekaClient.getApplications();
}

public void stop() {
    if (this.applicationInfoManager.getInfo() != null) {
        if (log.isInfoEnabled()) {
            log.info("Unregistering application " + this.instanceConfig.getAppname() + " with eureka with status DOWN");
        }

        this.applicationInfoManager.setInstanceStatus(InstanceStatus.DOWN);
    }

    this.running.set(false);
}


//監(jiān)聽(tīng),內(nèi)置容器啟動(dòng)時(shí)開(kāi)始注冊(cè)    
@EventListener({EmbeddedServletContainerInitializedEvent.class})
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
    int localPort = event.getEmbeddedServletContainer().getPort();
    if (this.port.get() == 0) {
        log.info("Updating port to " + localPort);
        this.port.compareAndSet(0, localPort);
        this.start();
    }

}

//監(jiān)聽(tīng)膛虫,應(yīng)用關(guān)閉時(shí)關(guān)閉eureka客戶端
@EventListener({ContextClosedEvent.class})
public void onApplicationEvent(ContextClosedEvent event) {
    this.stop();
    this.eurekaClient.shutdown();
}
}

按猜想的來(lái)說(shuō)應(yīng)該有一個(gè)Rest請(qǐng)求什么的將服務(wù)器信息發(fā)送到eureka服務(wù)器才對(duì)空闲,好像上面的start()方法沒(méi)有做什么事情。

我們關(guān)閉了eureka注冊(cè)中心走敌,重新啟動(dòng)服務(wù)碴倾,發(fā)現(xiàn)報(bào)了如下錯(cuò):


image.png

嗯,意料之中,肯定連不上啊跌榔,從這里可以看出异雁,發(fā)請(qǐng)求是RedirectingEurekaHttpClient請(qǐng)求客戶端做的,接著往下:


image.png

就像一開(kāi)始猜想的僧须,DiscoveryClient里面有與eureka的通信操作纲刀,而InstanceInfoReplicator應(yīng)該是一個(gè)線程類。進(jìn)去看看:

DiscoveryClient使用@Singleton修飾担平,里面有這么兩個(gè)函數(shù)示绊,可以看出是注冊(cè)與續(xù)約:

boolean register() throws Throwable {
    logger.info("DiscoveryClient_" + this.appPathIdentifier + ": registering service...");

    EurekaHttpResponse httpResponse;
    try {
        httpResponse = this.eurekaTransport.registrationClient.register(this.instanceInfo);
    } catch (Exception var3) {
        logger.warn("{} - registration failed {}", new Object[]{"DiscoveryClient_" + this.appPathIdentifier, var3.getMessage(), var3});
        throw var3;
    }

    if (logger.isInfoEnabled()) {
        logger.info("{} - registration status: {}", "DiscoveryClient_" + this.appPathIdentifier, httpResponse.getStatusCode());
    }

    return httpResponse.getStatusCode() == 204;
}

boolean renew() {
    try {
        EurekaHttpResponse<InstanceInfo> httpResponse = this.eurekaTransport.registrationClient.sendHeartBeat(this.instanceInfo.getAppName(), this.instanceInfo.getId(), this.instanceInfo, (InstanceStatus)null);
        logger.debug("{} - Heartbeat status: {}", "DiscoveryClient_" + this.appPathIdentifier, httpResponse.getStatusCode());
        if (httpResponse.getStatusCode() == 404) {
            this.REREGISTER_COUNTER.increment();
            logger.info("{} - Re-registering apps/{}", "DiscoveryClient_" + this.appPathIdentifier, this.instanceInfo.getAppName());
            return this.register();
        } else {
            return httpResponse.getStatusCode() == 200;
        }
    } catch (Throwable var3) {
        logger.error("{} - was unable to send heartbeat!", "DiscoveryClient_" + this.appPathIdentifier, var3);
        return false;
    }
}

這個(gè)register()就是InstanceInfoReplicator的run方法里調(diào)用的,而InstanceInfoReplicator是在DiscoveryClient的構(gòu)造方法中實(shí)例化的暂论。

在eureka服務(wù)器端則是將服務(wù)信息存放在一個(gè)雙層Map里面褐,第一層的Key是服務(wù)名,第二層的Key是實(shí)例名:

    private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry = new ConcurrentHashMap();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末取胎,一起剝皮案震驚了整個(gè)濱河市展哭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闻蛀,老刑警劉巖匪傍,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異觉痛,居然都是意外死亡役衡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門薪棒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)映挂,“玉大人,你說(shuō)我怎么就攤上這事盗尸。” “怎么了帽撑?”我有些...
    開(kāi)封第一講書人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵泼各,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我亏拉,道長(zhǎng)扣蜻,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任及塘,我火速辦了婚禮莽使,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘笙僚。我一直安慰自己芳肌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著亿笤,像睡著了一般翎迁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上净薛,一...
    開(kāi)封第一講書人閱讀 51,610評(píng)論 1 305
  • 那天汪榔,我揣著相機(jī)與錄音,去河邊找鬼肃拜。 笑死痴腌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的燃领。 我是一名探鬼主播士聪,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼柿菩!你這毒婦竟也來(lái)了戚嗅?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤枢舶,失蹤者是張志新(化名)和其女友劉穎懦胞,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凉泄,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡躏尉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了后众。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胀糜。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蒂誉,靈堂內(nèi)的尸體忽然破棺而出教藻,到底是詐尸還是另有隱情,我是刑警寧澤右锨,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布括堤,位于F島的核電站,受9級(jí)特大地震影響绍移,放射性物質(zhì)發(fā)生泄漏悄窃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一蹂窖、第九天 我趴在偏房一處隱蔽的房頂上張望轧抗。 院中可真熱鬧,春花似錦瞬测、人聲如沸横媚。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)分唾。三九已至抗碰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绽乔,已是汗流浹背弧蝇。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留折砸,地道東北人看疗。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像睦授,于是被迫代替她去往敵國(guó)和親两芳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容