eureka源碼分析-DiscoveryClient

一、概要

上一篇文章大致分析了eureka的整體流程。eureka client通過(guò)一個(gè)定時(shí)器定時(shí)上報(bào)心跳信息到eureka server。并且會(huì)定時(shí)拉取eureka server的服務(wù)列表到本地。
這里存在幾個(gè)問(wèn)題。

  1. eureka server之間的數(shù)據(jù)一致性如何保證?
    eureka server是要cp,還是ap?
  2. eureka client和eureka server之間的一致性如何保證?
    獲取服務(wù)列表存在時(shí)延,有可能一個(gè)已經(jīng)失效的結(jié)點(diǎn)還會(huì)在client中保留一段時(shí)間,或者一個(gè)新加入的結(jié)點(diǎn)還沒(méi)有同步到client。如何解決這種問(wèn)題?
    這篇文章先對(duì)eureka client的源碼做了解。

二、源碼分析

客戶端核心的代碼在DiscoveryClient。


類關(guān)系圖

eureka實(shí)例在初始化的時(shí)候會(huì)調(diào)用initScheduledTasks的方法,初始化定時(shí)任務(wù),這里面就包含定時(shí)向eureka server上報(bào)心跳的任務(wù)。

/**
     * Initializes all scheduled tasks.
     */
    private void initScheduledTasks() {
...
// Heartbeat timer
            scheduler.schedule(
                    new TimedSupervisorTask(
                            "heartbeat",
                            scheduler,
                            heartbeatExecutor,
                            renewalIntervalInSecs,
                            TimeUnit.SECONDS,
                            expBackOffBound,
                            new HeartbeatThread()
                    ),
                    renewalIntervalInSecs, TimeUnit.SECONDS);
...

我們接下來(lái)看下心跳告警線程的代碼

/**
     * The heartbeat task that renews the lease in the given intervals.
     */
    private class HeartbeatThread implements Runnable {

        public void run() {
            if (renew()) {
                lastSuccessfulHeartbeatTimestamp = System.currentTimeMillis();
            }
        }
    }
/**
     * Renew with the eureka service by making the appropriate REST call
     */
    boolean renew() {
        EurekaHttpResponse<InstanceInfo> httpResponse;
        try {
            httpResponse = eurekaTransport.registrationClient.sendHeartBeat(instanceInfo.getAppName(), instanceInfo.getId(), instanceInfo, null);
            logger.info("{} - Heartbeat status: {}", PREFIX + appPathIdentifier, httpResponse.getStatusCode());
            if (httpResponse.getStatusCode() == 404) {
                REREGISTER_COUNTER.increment();
                logger.info("{} - Re-registering apps/{}", PREFIX + appPathIdentifier, instanceInfo.getAppName());
                return register();
            }
            return httpResponse.getStatusCode() == 200;
        } catch (Throwable e) {
            logger.error("{} - was unable to send heartbeat!", PREFIX + appPathIdentifier, e);
            return false;
        }
    }

eureka采用的也是http協(xié)議,如果返回404返回碼,客戶端會(huì)選擇重新注冊(cè)信息到eureka server。

http協(xié)議報(bào)文如下:

Hypertext Transfer Protocol
    PUT /eureka/v2/apps/SAMPLEREGISTERINGSERVICE/201709-07262?status=UP&lastDirtyTimestamp=1552742035025 HTTP/1.1\r\n
    DiscoveryIdentity-Name: DefaultClient\r\n
    DiscoveryIdentity-Version: 1.4\r\n
    DiscoveryIdentity-Id: 172.19.10.230\r\n
    Accept-Encoding: gzip\r\n
    Content-Length: 0\r\n
    Host: localhost:8080\r\n
    Connection: Keep-Alive\r\n
    User-Agent: Java-EurekaClient/v<version_unknown>\r\n
    \r\n
    [Full request URI: http://localhost:8080/eureka/v2/apps/SAMPLEREGISTERINGSERVICE/201709-07262?status=UP&lastDirtyTimestamp=1552742035025]
    [HTTP request 1/1]
    [Response in frame: 7296]

。。。to be continued

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容