Eureka源码之服务获取与服务续约

首先看一下DiscoveryClient的initScheduledTasks函数,可以看到其中有两个定时任务,分别是“服务获取”和“服务续约”。

private void initScheduledTasks() {

        if (clientConfig.shouldFetchRegistry()) {

            // registry cache refresh timer

            int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();

            int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();

            scheduler.schedule(

                    new TimedSupervisorTask(

                            "cacheRefresh",

                            scheduler,

                            cacheRefreshExecutor,

                            registryFetchIntervalSeconds,

                            TimeUnit.SECONDS,

                            expBackOffBound,

                            new CacheRefreshThread()

                    ),

                    registryFetchIntervalSeconds, TimeUnit.SECONDS);

        }



        if (clientConfig.shouldRegisterWithEureka()) {

            int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();

            int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();

            logger.info("Starting heartbeat executor: " + "renew interval is: {}", renewalIntervalInSecs);



            // Heartbeat timer

            scheduler.schedule(

                    new TimedSupervisorTask(

                            "heartbeat",

                            scheduler,

                            heartbeatExecutor,

                            renewalIntervalInSecs,

                            TimeUnit.SECONDS,

                            expBackOffBound,

                            new HeartbeatThread()

                    ),

                    renewalIntervalInSecs, TimeUnit.SECONDS);



            ...

    }

从源码中,可以看到,“服务获取”任务相对于“服务续约”和“服务注册”任务更为独立。“服务续约”和“服务注册”在同一个if逻辑中,这个不难理解,服务注册到Eureka Server后,自然需要一个心跳去续约,防止被剔除,所以他们一起出现。从源码中,我们更清楚地看到之前提到的,对于服务续约相关的时间控制参数:

    public static final int DEFAULT_LEASE_RENEWAL_INTERVAL = 30;

    public static final int DEFAULT_LEASE_DURATION = 90;

而“服务获取”的逻辑在一个独立的if判断中,其判断依据是eureka.client.fetch-registery=true参数,它默认为true,大部分情况我们不需要关心。为了定期更新客户端的服务清单,以保证客户端能够访问确实健康的附录实例,“服务获取”的请求不会只限于服务启动,而是一个定时的任务,从源码中,我们可以看到任务运行中的registryFetchIntervalSeconds参数对应的就是eureka.client.reegistry-fetch-internal-seconds=30配置参数,它默认为30秒。

“服务续约”的实现比较简单,直接以REST请求方式进行续约,相关代码如下:    

boolean renew() {

        EurekaHttpResponse httpResponse;

        try {

            httpResponse = eurekaTransport.registrationClient.sendHeartBeat(instanceInfo.getAppName(), instanceInfo.getId(), instanceInfo, null);

            logger.debug(PREFIX + "{} - Heartbeat status: {}", appPathIdentifier, httpResponse.getStatusCode());

            if (httpResponse.getStatusCode() == Status.NOT_FOUND.getStatusCode()) {

                REREGISTER_COUNTER.increment();

                logger.info(PREFIX + "{} - Re-registering apps/{}", appPathIdentifier, instanceInfo.getAppName());

                long timestamp = instanceInfo.setIsDirtyWithTime();

                boolean success = register();

                if (success) {

                    instanceInfo.unsetIsDirty(timestamp);

                }

                return success;

            }

            return httpResponse.getStatusCode() == Status.OK.getStatusCode();

        } catch (Throwable e) {

            logger.error(PREFIX + "{} - was unable to send heartbeat!", appPathIdentifier, e);

            return false;

        }

    }

而“服务获取”则复杂一些,会根据是否是第一次获取发起不同的REST请求和相应的处理。

 

你可能感兴趣的:(微服务)