eureka

eureka源码分析-DiscoveryClient

2019-03-31  本文已影响0人  leiwingqueen

一、概要

上一篇文章大致分析了eureka的整体流程。eureka client通过一个定时器定时上报心跳信息到eureka server。并且会定时拉取eureka server的服务列表到本地。
这里存在几个问题。

  1. eureka server之间的数据一致性如何保证?
    eureka server是要cp,还是ap?
  2. eureka client和eureka server之间的一致性如何保证?
    获取服务列表存在时延,有可能一个已经失效的结点还会在client中保留一段时间,或者一个新加入的结点还没有同步到client。如何解决这种问题?
    这篇文章先对eureka client的源码做了解。

二、源码分析

客户端核心的代码在DiscoveryClient。


类关系图

eureka实例在初始化的时候会调用initScheduledTasks的方法,初始化定时任务,这里面就包含定时向eureka server上报心跳的任务。

/**
     * 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);
...

我们接下来看下心跳告警线程的代码

/**
     * 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协议,如果返回404返回码,客户端会选择重新注册信息到eureka server。

http协议报文如下:

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

上一篇下一篇

猜你喜欢

热点阅读