Spring Cloud Eureka服务如何实现心跳续约机制?

2026-05-21 03:363阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计777个文字,预计阅读时间需要4分钟。

Spring Cloud Eureka服务如何实现心跳续约机制?

前言:Eureka Client的应用启动时,在com.netflix.discovery.DiscoveryClient类的initScheduledTasks方法中,会执行以下几件事:

1. 周期性更新服务列表;

2.周期性续约服务;

3.服务注册逻辑;

4.概览信息。

前言

Eureka Client的应用启动时,在com.netflix.discovery.DiscoveryClient类的initScheduledTasks方法中,会做以下几件事:

  • 1、周期性更新服务列表;
  • 3、周期性服务续约;
  • 3、服务注册逻辑;

概览

以下图片来自Netflix官方,图中显示Eureka Client会发起Renew向注册中心做周期性续约,这样其他Eureka client通过Get Registry请求就能获取到新注册应用的相关信息:

来自官方文档的指导信息

最准确的说明信息来自Netflix的官方文档,地址: github.com/Netflix/eureka/wiki/Understanding-eureka-client-server-communication#renew

关于续约的理解:

  • 1、Eureka client每隔三十秒发送一次心跳到Eureka server,这就是续约;
  • 2、Eureka client续约的目的是告诉Eureka server自己还活着;
  • 3、Eureka server若90秒内未收到心跳,就从自己的服务列表中剔除该Eureka client;
  • 4、建议不要改变心跳间隔,因为Eureka server是通过心跳来判断Eureka client是否正常;

服务续约执行简要流程图

下面这张图大致描述了服务续约从Client端到Server端的大致流程,详情如下:

Eureka 续约源码分析

1、Eureka Client发起续约

Eureka Client向Eureka Server发起注册应用实例成功后获得租约,Eureka Client固定间隔向Eureka Server发起续约(renew),避免租约过期。

 

默认情况下,租约有效期为90秒,续约频率为30秒。两者比例为1:3,保证在网络异常等情况下,有三次重试的机会。

1)、初始化定时任务

Eureka Client在初始化过程中,创建心跳线程,固定间隔向Eureka Server发起续约。实现代码如下

@Singleton public class DiscoveryClient implements EurekaClient { /** * 初始化所有计划的任务 */ private void initScheduledTasks() { //获取注册信息的定时任务 if (clientConfig.shouldFetchRegistry()) { // registry cache refresh timer int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds(); int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound(); cacheRefreshTask = new TimedSupervisorTask( "cacheRefresh", scheduler, cacheRefreshExecutor, registryFetchIntervalSeconds, TimeUnit.SECONDS, expBackOffBound, new CacheRefreshThread() ); scheduler.schedule( cacheRefreshTask, 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 heartbeatTask = new TimedSupervisorTask( "heartbeat", scheduler, heartbeatExecutor, renewalIntervalInSecs, TimeUnit.SECONDS, expBackOffBound, new HeartbeatThread() ); scheduler.schedule( heartbeatTask, renewalIntervalInSecs, TimeUnit.SECONDS); //服务实例同步定时任务 // InstanceInfo replicator instanceInfoReplicator = new InstanceInfoReplicator( this, instanceInfo, clientConfig.getInstanceInfoReplicationIntervalSeconds(), 2); // burstSize 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); } instanceInfoReplicator.onDemandUpdate(); } }; // 注册应用实例状态变更监听器 if (clientConfig.shouldOnDemandUpdateStatusChange()) { applicationInfoManager.registerStatusChangeListener(statusChangeListener); } //初始化定时服务注册任务 instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds()); } else { logger.info("Not registering with Eureka server per configuration"); } } }

2)、发起续约

@Singleton public class DiscoveryClient implements EurekaClient { //最后成功向Eureka Server心跳时间戳 private volatile long lastSuccessfulHeartbeatTimestamp = -1; private class HeartbeatThread implements Runnable { public void run() { // 调用续约方法 if (renew()) { lastSuccessfulHeartbeatTimestamp = System.currentTimeMillis(); } } } //服务续约 boolean renew() { EurekaHttpResponse<InstanceInfo> xinchen.blog.csdn.net/article/details/82915355

blog.csdn.net/qq_40378034/article/details/119079180

blog.csdn.net/NEW_BUGGER/article/details/93710797

www.cnblogs.com/liujunj/p/13401808.html

Spring Cloud Eureka服务如何实现心跳续约机制?

本文共计777个文字,预计阅读时间需要4分钟。

Spring Cloud Eureka服务如何实现心跳续约机制?

前言:Eureka Client的应用启动时,在com.netflix.discovery.DiscoveryClient类的initScheduledTasks方法中,会执行以下几件事:

1. 周期性更新服务列表;

2.周期性续约服务;

3.服务注册逻辑;

4.概览信息。

前言

Eureka Client的应用启动时,在com.netflix.discovery.DiscoveryClient类的initScheduledTasks方法中,会做以下几件事:

  • 1、周期性更新服务列表;
  • 3、周期性服务续约;
  • 3、服务注册逻辑;

概览

以下图片来自Netflix官方,图中显示Eureka Client会发起Renew向注册中心做周期性续约,这样其他Eureka client通过Get Registry请求就能获取到新注册应用的相关信息:

来自官方文档的指导信息

最准确的说明信息来自Netflix的官方文档,地址: github.com/Netflix/eureka/wiki/Understanding-eureka-client-server-communication#renew

关于续约的理解:

  • 1、Eureka client每隔三十秒发送一次心跳到Eureka server,这就是续约;
  • 2、Eureka client续约的目的是告诉Eureka server自己还活着;
  • 3、Eureka server若90秒内未收到心跳,就从自己的服务列表中剔除该Eureka client;
  • 4、建议不要改变心跳间隔,因为Eureka server是通过心跳来判断Eureka client是否正常;

服务续约执行简要流程图

下面这张图大致描述了服务续约从Client端到Server端的大致流程,详情如下:

Eureka 续约源码分析

1、Eureka Client发起续约

Eureka Client向Eureka Server发起注册应用实例成功后获得租约,Eureka Client固定间隔向Eureka Server发起续约(renew),避免租约过期。

 

默认情况下,租约有效期为90秒,续约频率为30秒。两者比例为1:3,保证在网络异常等情况下,有三次重试的机会。

1)、初始化定时任务

Eureka Client在初始化过程中,创建心跳线程,固定间隔向Eureka Server发起续约。实现代码如下

@Singleton public class DiscoveryClient implements EurekaClient { /** * 初始化所有计划的任务 */ private void initScheduledTasks() { //获取注册信息的定时任务 if (clientConfig.shouldFetchRegistry()) { // registry cache refresh timer int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds(); int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound(); cacheRefreshTask = new TimedSupervisorTask( "cacheRefresh", scheduler, cacheRefreshExecutor, registryFetchIntervalSeconds, TimeUnit.SECONDS, expBackOffBound, new CacheRefreshThread() ); scheduler.schedule( cacheRefreshTask, 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 heartbeatTask = new TimedSupervisorTask( "heartbeat", scheduler, heartbeatExecutor, renewalIntervalInSecs, TimeUnit.SECONDS, expBackOffBound, new HeartbeatThread() ); scheduler.schedule( heartbeatTask, renewalIntervalInSecs, TimeUnit.SECONDS); //服务实例同步定时任务 // InstanceInfo replicator instanceInfoReplicator = new InstanceInfoReplicator( this, instanceInfo, clientConfig.getInstanceInfoReplicationIntervalSeconds(), 2); // burstSize 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); } instanceInfoReplicator.onDemandUpdate(); } }; // 注册应用实例状态变更监听器 if (clientConfig.shouldOnDemandUpdateStatusChange()) { applicationInfoManager.registerStatusChangeListener(statusChangeListener); } //初始化定时服务注册任务 instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds()); } else { logger.info("Not registering with Eureka server per configuration"); } } }

2)、发起续约

@Singleton public class DiscoveryClient implements EurekaClient { //最后成功向Eureka Server心跳时间戳 private volatile long lastSuccessfulHeartbeatTimestamp = -1; private class HeartbeatThread implements Runnable { public void run() { // 调用续约方法 if (renew()) { lastSuccessfulHeartbeatTimestamp = System.currentTimeMillis(); } } } //服务续约 boolean renew() { EurekaHttpResponse<InstanceInfo> xinchen.blog.csdn.net/article/details/82915355

blog.csdn.net/qq_40378034/article/details/119079180

blog.csdn.net/NEW_BUGGER/article/details/93710797

www.cnblogs.com/liujunj/p/13401808.html

Spring Cloud Eureka服务如何实现心跳续约机制?