《Spring Cloud 》Eureka服务调用服务超时重试机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Spring Cloud 》Eureka服务调用服务超时重试机制相关的知识,希望对你有一定的参考价值。
参考技术A 问题根源有二:1):业务耗时时间比较长,超过服务调用超时时间配置,由于Spring Cloud 服务调用超时重试机制默认开启,所以会导致服务被调用了两次。
2):服务端未做幂等性,导致重复的业务处理。
增大配置超时时间
ribbon.ReadTimeout=10000
ribbon.ConnectTimeout=10000
eureka服务调用重试开关的配置属性:
默认开启。
重试机制:对于连接超时的异常,feign都会触发重试机制,对于读取超时,会根据请求类型判断,如果是GET异常,触发重试;其他异常,不会触发重试。
服务响应超时时间,默认5s,连接的超时时间为2s。
同一实例最大重试次数为1
负载均衡的其他实例的重试次数为2
对所有操作请求都进行重试,默认false,建议不要开启。
Spring Cloud Eureka服务注册源码分析
Eureka是怎么work的
那eureka client如何将本地服务的注册信息发送到远端的注册服务器eureka server上。通过下面的源码分析,看出Eureka Client的定时任务调用Eureka Server的Reset接口,而Eureka接收到调用请求后会处理服务的注册以及Eureka Server中的数据同步的问题。
服务注册
源码分析,看出服务注册可以认为是Eureka client自己完成,不需要服务本身来关心。
Eureka Client的定时任务调用Eureka Server的提供接口
在com.netflix.discovery.DiscoveryClient启动的时候,会初始化一个定时任务,定时的把本地的服务配置信息,即需要注册到远端的服务信息自动刷新到注册服务器上。
首先看一下Eureka的代码,在spring-cloud-netflix-eureka-server工程中可以找到这个依赖eureka-client-1.4.11.jar查看代码可以看到,
com.netflix.discovery.DiscoveryClient.java中的1240行可以看到Initializes all scheduled tasks,在1277行,可以看到InstanceInfoReplicator定时任务
在DiscoveryClient中初始化一个InstanceInfoReplicator,其实里面封装了以定时任务。
/** * Initializes all scheduled tasks. */ 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); // 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); } //点击可以查看start方法 instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds()); } else { logger.info("Not registering with Eureka server per configuration"); } }
EurekaHttpClient :提供eureka 的客户端API方法
以上是关于《Spring Cloud 》Eureka服务调用服务超时重试机制的主要内容,如果未能解决你的问题,请参考以下文章
springcloud学习03-spring cloud eureka
Java之 Spring Cloud 微服务 Eureka (第一个阶段)SpringBoot项目实现商品服务器端是调用