springcloud之Feign、ribbon如何设置超时时间和重试机制

Feign、ribbon设置超时时间和重试机制

前言

我们在微服务调用服务的时候,会使用feign和ribbon,比如有一个实例发生了故障而该情况还没有被服务治理机制及时的发现和摘除,这时候客户端访问该节点的时候自然会失败。

所以,为了构建更为健壮的应用系统,我们希望当请求失败的时候能够有一定策略的重试机制,而不是直接返回失败。

先看一个配置:

#预加载配置,默认为懒加载
ribbon:
  eager-load:
    enabled: true
    clients: zoo-plus-email

zoo-plus-email:
  ribbon:
    # 代表Ribbon使用的负载均衡策略
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    # 每台服务器最多重试次数,但是首次调用不包括在内
    MaxAutoRetries: 1
    # 最多重试多少台服务器
    MaxAutoRetriesNextServer: 1
    # 无论是请求超时或者socket read timeout都进行重试
    OkToRetryOnAllOperations: true
    ReadTimeout: 3000
    ConnectTimeout: 3000

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 4000

一般情况下 都是 ribbon 的超时时间(<)hystrix的超时时间(因为涉及到ribbon的重试机制)

Feign重试:

因为ribbon的重试机制和Feign的重试机制有冲突,所以源码中默认关闭Feign的重试机制,具体看一看源码

要开启Feign的重试机制如下:(Feign默认重试五次 源码中有)

@Bean
Retryer feignRetryer() {
        return  new Retryer.Default();
}

ribbon的重试机制 :

ribbon:
  ReadTimeout: 3000
  ConnectTimeout: 3000
  MaxAutoRetries: 1 #同一台实例最大重试次数,不包括首次调用
  MaxAutoRetriesNextServer: 1 #重试负载均衡其他的实例最大重试次数,不包括首次调用
  OkToRetryOnAllOperations: false  #是否所有操作都重试 

计算重试的次数:

MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries *MaxAutoRetriesNextServer) 

即重试3次 加上第一次调用一共产生4次调用 。

注意:如果在重试期间,时间超过了hystrix的超时时间,便会立即执行熔断,fallback。所以要根据上面配置的参数计算hystrix的超时时间,使得在重试期间不能达到hystrix的超时时间,不然重试机制就会没有意义 。

hystrix超时时间的计算:

(1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout 

即按照以上的配置 hystrix的超时时间应该配置为 (1+1+1)*3=9秒

当ribbon超时后且hystrix没有超时,便会采取重试机制。当OkToRetryOnAllOperations设置为false时,只会对get请求进行重试。如果设置为true,便会对所有的请求进行重试,如果是put或post等写操作,如果服务器接口没做幂等性,会产生不好的结果,所以OkToRetryOnAllOperations慎用。

如果不配置ribbon的重试次数,默认会重试一次

注意: 默认情况下,GET方式请求无论是连接异常还是读取异常,都会进行重试 ,非GET方式请求,只有连接异常时,才会进行重试

Feign、Ribbon、Hystrix三者超时时间配置

Feign设置

feign:
  hystrix:
    enabled: true
  client:
    config:
      # 全局配置
      default:
        connectTimeout: 5000
        readTimeout: 5000
      # 实例配置,feignName即@feignclient中的value,也就是服务名
      feignName:
        connectTimeout: 5000
        readTimeout: 5000

Ribbon设置

# 全局配置
ribbon:
# 单个服务最大重试次数,不包含对单个服务的第一次请求,默认0
MaxAutoRetries: 3
# 服务切换次数,不包含最初的服务,如果服务注册列表小于 nextServer count 那么会循环请求  A > B > A,默认1
MaxAutoRetriesNextServer: 2
#是否所有操作都进行重试,默认只重试get请求,如果修改为true,则需注意post\put等接口幂等性
OkToRetryOnAllOperations: false
#连接超时时间,单位为毫秒,默认2秒
ConnectTimeout: 3000
#读取的超时时间,单位为毫秒,默认5秒
ReadTimeout: 3000
# 实例配置
clientName:
 ribbon:
  MaxAutoRetries: 5
  MaxAutoRetriesNextServer: 3
  OkToRetryOnAllOperations: false
  ConnectTimeout: 3000
  ReadTimeout: 3000

Hystrix设置

hystrix:
 command:
   #全局默认配置
   default:
     #线程隔离相关
     execution:
       timeout:
         #是否给方法执行设置超时时间,默认为true。一般我们不要改。
         enabled: true
       isolation:
         #配置请求隔离的方式,这里是默认的线程池方式。还有一种信号量的方式semaphore。
         strategy: THREAD
         thread:
           #方式执行的超时时间,默认为1000毫秒,在实际场景中需要根据情况设置
           timeoutInMilliseconds: 10000
   # 实例配置
   HystrixCommandKey:
     execution:
       timeout:
         enabled: true
       isolation:
         strategy: THREAD
         thread:
           timeoutInMilliseconds: 10000

Feign重试和Ribbon重试

feign自身重试目前只有一个简单的实现Retryer.Default,包含三个属性:

  • maxAttempts:重试次数,包含第一次
  • period:重试初始间隔时间,单位毫秒
  • maxPeriod:重试最大间隔时间,单位毫秒

ribbon重试包含两个属性:MaxAutoRetries和MaxAutoRetriesNextServer

总重试次数= 访问的服务器数 * 单台服务器最大重试次数

即:(1+MaxAutoRetriesNextServer)*(1+MaxAutoRetries )

按上面实例的配置,则总重试次数 =(1+2)*(1+3) = 12

超时时间设置

feign和ribbon的超时时间只会有一个生效,规则:如果没有设置过feign超时,也就是等于默认值的时候,就会读取ribbon的配置,使用ribbon的超时时间和重试设置。否则使用feign自身的设置。两者是二选一的,且feign优先。

以Ribbon的时间生效为例,Hystrix的超时时间需大于Ribbon重试总和时间,否则重试将失效,即: Hystrix超时时间 > (Ribbon超时时间总和)*重试次数

按上面的例子,hystrix超时时间>12*(3000+3000)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • springcloud之Feign超时问题的解决

    问题背景 最近公司项目有个功能需进行三层Feign调用,且还要调外部接口,延迟挺大,造成Feign一直提示Read timed out executing POST. feign.RetryableException: Read timed out executing POST http://****** at feign.FeignException.errorExecuting(FeignException.java:67) at feign.SynchronousMethodHandler

  • Spring Cloud重试机制与各组件的重试总结

    SpringCloud重试机制配置 首先声明一点,这里的重试并不是报错以后的重试,而是负载均衡客户端发现远程请求实例不可到达后,去重试其他实例. @Bean @LoadBalanced RestTemplate restTemplate() { HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(); httpRequestFactory.se

  • Spring Cloud Ribbon配置详解

    本节我们主要介绍 Ribbon 的一些常用配置和配置 Ribbon 的两种方式. 常用配置 1. 禁用 Eureka 当我们在 RestTemplate 上添加 @LoadBalanced 注解后,就可以用服务名称来调用接口了,当有多个服务的时候,还能做负载均衡. 这是因为 Eureka 中的服务信息已经被拉取到了客户端本地,如果我们不想和 Eureka 集成,可以通过下面的配置方法将其禁用. # 禁用 Eureka ribbon.eureka.enabled=false 当我们禁用了 Eure

  • feign的ribbon超时配置和hystrix的超时配置说明

    先看下我的配置: ribbon: MaxAutoRetries: 1 #最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试 MaxAutoRetriesNextServer: 1 #切换实例的重试次数 OkToRetryOnAllOperations: false # 对所有的操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false ConnectTimeout: 1000 #请求连接的超时时间 ReadTimeo

  • Spring Cloud Feign 自定义配置(重试、拦截与错误码处理) 代码实践

    基于 spring-boot-starter-parent 2.1.9.RELEASE, spring-cloud-openfeign 2.1.3.RELEASE 引子 Feign 是一个声明式.模板化的HTTP客户端,简化了系统发起Http请求.创建它时,只需要创建一个接口,然后加上FeignClient注解,使用它时,就像调用本地方法一样,作为开发者的我们完全感知不到这是在调用远程的方法,也感知不到背后发起了HTTP请求: /** * @author axin * @suammry xx 客

  • springcloud之Feign、ribbon如何设置超时时间和重试机制

    Feign.ribbon设置超时时间和重试机制 前言 我们在微服务调用服务的时候,会使用feign和ribbon,比如有一个实例发生了故障而该情况还没有被服务治理机制及时的发现和摘除,这时候客户端访问该节点的时候自然会失败. 所以,为了构建更为健壮的应用系统,我们希望当请求失败的时候能够有一定策略的重试机制,而不是直接返回失败. 先看一个配置: #预加载配置,默认为懒加载 ribbon: eager-load: enabled: true clients: zoo-plus-email zoo-

  • feign客户端设置超时时间操作

    我就废话不多说了,大家还是直接看代码吧~ /** * feign调用客户端 */ @FeignClient(name = "user", url = "${user.url}", configuration = MyFeignDecoder.class) public interface UserClient { @GetMapping("/rest/user/get/detail/{loginName}") JSONObject getUser

  • 客户端设置超时时间真的很重要

    概述 在一条慢SQL导致购物车服务无法使用的解决方案一文中,提到了客户端调用购物车服务的时候,超时了.如果当时客户端没有设置超时时间的话,会在客户端中产生级联故障.先用一张图来说明一下. 聚合层除了调用购物车微服务,还调用了营销系统微服务.如果购物车服务的接口响应时间很慢,而客户端聚合层调用购物车服务时,又没有设置超时时间,那么将占有大量的连接,如果请求购物车服务的请求量比较大,瞬间就会把连接占用完,直接导致聚合层调用营销系统时,需要阻塞住等待获取连接,这样的话,整个小程序的很多功能就都用不了了

  • PHP请求远程地址设置超时时间的解决方法

    php请求远程地址设置超时时间,主要讲解file_get_contents.fopen.curl这三个简单常用函数设置超时时间的方法,一般情况下建议使用curl,性能最好,效率也最高. 1.file_get_contents 请求超时设置 $timeout = array( 'http'=> array( 'timeout'=>5//设置一个超时时间,单位为秒 ) ); $ctx = stream_context_create($timeout); $text = file_get_conte

  • C++设置超时时间的简单实现方法

    本文实例讲述了C++设置超时时间的简单实现方法,代码简单易懂,功能实用.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: BOOL SetTimeOut(SOCKET s, int nTime, BOOL bRecv)  {      int ret = ::setsockopt(s, SOL_SOCKET, bRecv?SO_RCVTIMEO:SO_SNDTIMEO, (char*)nTime, sizeof(nTime));      return ret!=SOCKET_ER

  • java httpclient设置超时时间和代理的方法

    设置超时时间 设置HttpClient的超时时间,非常有必要性,因为httpclient 默认超时时间很长,自己可以测试一下是多久,设置超时时间否则会影响自己系统的业务逻辑,例如阻塞系统,影响系统的吞吐量,占用线程数. httpclient 4.4版本之后将这些设置封装到 RequestConfig 对象里,其中 setConnectTimeout 是设置连接到目标 URL 的等待时长,超过这个时间还没连上就抛出连接超时: setConnectionRequestTimeout 是从connec

  • Springboot RestTemplate设置超时时间的简单方法

    目录 排查: Java Config配置 配置文件指定 RestTemplate 设置超时时间注意点 总结 RestTemplate未设置超时时间,导致RabbitMQ队列大量堆积,消费者假死,不进行消费,类似线程堵塞. 排查: 从日志排查问题,在从进入消费者到结束期间,会调用业务服务,然而通过开始时间至结束时间,花费的时间竟然高达100多秒,查看业务服务未发现异常.出现这种问题的原因也有可能在消费期间网络波动导致HTTP连接出现问题,一直处于等待状态.由此判断可能是HTTP超时时间未设置导致的

  • 一次.net core异步线程设置超时时间的实战记录

    目录 前言: 需求背景: 需求提炼: .net里设置超时的 Task 测试代码 测试截图 搞定收工 总结 前言: 刷帖子看到一篇 Go 记录一次groutine通信与context控制 看了一下需求背景,挺有意思的,琢磨了下.net core下的实现 需求背景: 项目中需要定期执行任务A来做一些辅助的工作,A的执行需要在超时时间内完成,如果本次执行超时了,那就不对本次的执行结果进行处理(即放弃这次执行).同时A又依赖B,C两个子任务的执行结果.B, C之间相互独立,可以并行的执行.但无论B,C哪

  • RestTemplate设置超时时间及返回状态码非200处理

    目录 1.调试postForEntity请求 2.设置超时时间 默认情况下使用RestTemplate如果返回结果的状态码是200的话就正常处理,否则都会抛出异常: 1.调试postForEntity请求 调试postForEntity请求的方法找到判断响应结果状态码的方法是org.springframework.web.client.DefaultResponseErrorHandler类中的hasError方法 @Override public boolean hasError(Client

  • Redis分布式锁如何设置超时时间

    目录 Redis分布式锁设置超时时间 网络抖动 Redis宕机 Redis分布式锁的超时问题 Redis分布式锁设置超时时间 Redis分布式锁主要依靠Redis服务来完成,我们的应用程序其实是Redis节点的客户端,一旦客户端没有释放锁,服务端就会一直持有这个锁,其他进程中的线程就无法获取到这把锁,于是就会发生锁死的情况. 所以我们在使用Redis分布式锁的时候,务必要设置锁的过期时间. 主要基于下面两点: 网络抖动 客户端A中的一个线程获取到了锁,然后执行finally中的释放锁的代码时,这

随机推荐