美文网首页spring cloud
feign和hystrix的超时配置总结 以及 Hystrix的

feign和hystrix的超时配置总结 以及 Hystrix的

作者: virtual灬zzZ | 来源:发表于2021-11-01 19:12 被阅读0次
#参考官方配置 https://docs.spring.io/spring-cloud-openfeign/docs/2.2.5.RELEASE/reference/html/
feign:
  client:
    config:
      default:
        connectTimeout: 1000
        readTimeout: 5000
  hystrix:
    enabled: true

#在feign和hystrix共存时,hystrix可以配置自身降级时间,默认1s
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000 # 设置hystrix的超时时间为6000ms
      circuitBreaker:
        #在当10秒的时间内,最近20次调用请求,请求错误率超过60%,则触发熔断5秒,期间快速失败,以下都是默认值
        requestVolumeThreshold: 20
        errorThresholdPercentage: 50
        sleepWindowInMilliseconds: 5000
      #设置统计的时间窗口值的毫秒值,circuit break 的打开会根据1个rolling window的统计来计算。
      #若rolling window被设为10000毫秒,则rolling window会被分成n个buckets,
      #每个bucket包含success,failure,timeout,rejection的次数的统计信息。默认10000。
      metrics:
          rollingStats:
            timeInMilliseconds: 10000

feign

  • ConnectTimeout

    指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间。
    在java中,网络状况正常的情况下,例如使用HttpClient或者HttpURLConnetion连接时设置参数connectTimeout=5000即5秒,如果连接用时超过5秒就是抛出java.net.SocketException: connetct time out的异常

  • ReadTimeout

    指的是建立连接后从服务器读取到可用资源所用的时间。
    在这里我们可以这样理解ReadTimeout:正常情况下,当我们发出请求时可以收到请求的结果,也就是页面上展示的内容,但是当网络状况很差的时候,就会出现页面上无法展示出内容的情况。另外当我们使用爬虫或者其他全自动的程序时,无法判断当前的网络状况是否良好,此时就有了ReadTimeout的用武之地了,通过设置ReadTimeout参数,例:ReadTimeout=5000,超过5秒没有读取到内容时,就认为此次读取不到内容并抛出Java.net.SocketException: read time out的异常。

根据上面关于ConnectTimeout和ReadTimeout的描述,在我们使用需要设置这两项参数的服务或程序时,应该对两项参数一起设置。

一般而言两项参数的数值可以设置成一样的,可以适当把ReadTimeout设置的长一点,ConnectTimeout可以相对比较短,这是源于我们的网络状况一般较为稳定,连接时很少出现问题,但是读取时因为数据下载时的网络波动,出状况的可能性更大一些。

测试,

1. 双边连接良好

① 只设置hystrix(5s),feign的ReadTimeout、ConnectTimeout均不设置,服务方sleep1/2/3秒,结果都如下:
调用方显示了Read timed out,触发了降级,并且有进行了重试,重试了1次,间隔1秒。

############################# 第一次
1635755154447 --port : 7000 --- testHystrixSleep : 3
1635755155207 --port : 7000 --- testHystrixSleep : 3

############################# 第二次

1635755167963 --port : 7000 --- testHystrixSleep : 3
1635755168972 --port : 7000 --- testHystrixSleep : 3
由此可得 feign 的 readTimeout 默认是1s。

② 设置hystrix(5s),feign的ReadTimeout为2s,connectTimeout不设置:
服务方sleep 1s,正常返回,
服务方sleep 2s,降级,没有重试。

由此可得,在连接正常的情况下,有设置readTimeout且少于请求时间,降级只取决于readTimeout的时间。

③ 设置hystrix(5s),feign的connectTimeout为1/2s,ReadTimeout不设置:
服务方sleep 2s,无论connectTimeout是1s 还是 2s,均返回正常结果,没有重试。

由此可得,在连接正常的情况下,readTimeout的默认时间(1s)是不起效的,只取决于hystrix的时间。

④ 设置hystrix(5s),feign的connectTimeout(1s),ReadTimeout(2s)
服务方sleep 2s,直接降级,没有重试

⑤ 设置hystrix(3s),feign的connectTimeout(1s),ReadTimeout(4s)
服务方sleep 3s,直接降级,没有重试
服务方sleep 2s,正常返回

由此可得,在连接正常的情况下,hystrix、readTimeout的值取决于最小那个。

2. 停掉了服务方

①. 只设置hystrix(10s),feign的ReadTimeout、ConnectTimeout均不设置,结果都如下

2021-11-01 18:12:57.906 DEBUG 20248 --- [trix-provider-1] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] ---> GET http://provider/providerHystrix HTTP/1.1
2021-11-01 18:12:57.906 DEBUG 20248 --- [trix-provider-1] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] ---> END HTTP (0-byte body)
由此可得一下就没了。

②只设置hystrix(10s),feign的ReadTimeout(4s)、ConnectTimeout(2s)均设置,ConnectTimeout,结果都如下

2021-11-01 18:09:37.516 DEBUG 7852 --- [trix-provider-2] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] ---> GET http://provider/providerHystrix HTTP/1.1
2021-11-01 18:09:37.517 DEBUG 7852 --- [trix-provider-2] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] ---> END HTTP (0-byte body)
2021-11-01 18:09:39.537 DEBUG 7852 --- [trix-provider-2] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] <--- ERROR SocketTimeoutException: connect timed out (2018ms)
由此可得还是取决 feign配置 的connectTimeout。

总结:

综上可得,其实在正常连接情况,都把connectTimeout配置比readTimeout小的,hystrix默认是1秒,而readTimeout也是1秒,但有时业务处理是不止1s的,所以最好配置1s以上(不用默认值),在配置hystrix的同时,也要配置好connectTimeout和readTimeout,而且上述测试可知,在readTimeout和hystrix同时在的情况下,谁小就谁决定降级时间,所以一般就把它们设置一样就好了。

----------------------------------- 分割线 -----------------------------------------

Hystrix的 局部降级 和 全局降级

首先看下,在上诉的例子里,得到的降级日志是怎么样的,我们能得到什么信息,为我们后续的局部、全局的hystrix的配置提供有效信息。

服务方会sleep 4s ,而调用方的配置如下:

feign:
  hystrix:
    enabled: true
  okhttp:
    enabled: true
  client:
    config:
      default:
        connectTimeout: 2000
        readTimeout: 10000

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 # 设置hystrix的超时时间,默认1s
2021-11-01 18:51:54.933 DEBUG 12268 --- [trix-provider-6] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] ---> GET http://provider/providerHystrix HTTP/1.1
2021-11-01 18:51:54.933 DEBUG 12268 --- [trix-provider-6] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] ---> END HTTP (0-byte body)
2021-11-01 18:51:57.942 DEBUG 12268 --- [trix-provider-6] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] <--- ERROR SocketTimeoutException: Read timed out (3008ms)
2021-11-01 18:51:57.944 DEBUG 12268 --- [trix-provider-6] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    略...
2021-11-01 18:51:57.955 DEBUG 12268 --- [trix-provider-6] c.orion.service.TestFeignHystrixService  : [TestFeignHystrixService#providerHystrix] <--- END ERROR
我们得到了 TestFeignHystrixService#providerHystrix , 这是一个hystrixCommandKey,而hystrix配置的格式是这样的:hystrix.command.<HystrixCommandKey>.execution.isolation.thread.timeoutInMilliseconds: 100 ,默认是default即全局,而如果我们需要自定义某个方法,即自定义hystrixCommonKey,由日志得出,很显然HystrixCommandKey就是@feignClient描述的接口类以及调用方法(带参数类型)组成的。

所以进行以下配置测试:(附带上了circuitBreaker)

feign:
  hystrix:
    enabled: true
  okhttp:
    enabled: true
  client:
    config:
      default:
        connectTimeout: 2000
        readTimeout: 10000

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 # 设置hystrix的超时时间,默认1s
      circuitBreaker:
        #在当10秒的时间内,最近20次调用请求,请求错误率超过60%,则触发熔断5秒,期间快速失败,以下都是默认值
        requestVolumeThreshold: 20
        errorThresholdPercentage: 50
        sleepWindowInMilliseconds: 5000
      #设置统计的时间窗口值的毫秒值,circuit break 的打开会根据1个rolling window的统计来计算。
      #若rolling window被设为10000毫秒,则rolling window会被分成n个buckets,
      #每个bucket包含success,failure,timeout,rejection的次数的统计信息。默认10000。
      metrics:
        rollingStats:
          timeInMilliseconds: 10000
    TestFeignHystrixService#providerPartHystrix(Integer):
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 5000 # 设置hystrix的超时时间,默认1s
      circuitBreaker:
        #在当10秒的时间内,最近20次调用请求,请求错误率超过60%,则触发熔断5秒,期间快速失败,以下都是默认值
        requestVolumeThreshold: 20
        errorThresholdPercentage: 50
        sleepWindowInMilliseconds: 5000
      #设置统计的时间窗口值的毫秒值,circuit break 的打开会根据1个rolling window的统计来计算。
      #若rolling window被设为10000毫秒,则rolling window会被分成n个buckets,
      #每个bucket包含success,failure,timeout,rejection的次数的统计信息。默认10000。
      metrics:
        rollingStats:
          timeInMilliseconds: 10000

提供了一个providerPartHystrix(Integer a) 方法:

@Service
@FeignClient(value = "provider", fallback = TestFeignHystrixServiceFallback.class)
public interface TestFeignHystrixService {

    @GetMapping("/providerHystrix") //hystrix降级配置3秒 ,服务方sleep 4秒
    Result providerHystrix();

    @GetMapping("/providerPartHystrix")   //hystrix降级配置5秒 ,服务方sleep 4秒
    Result providerPartHystrix(@RequestParam("a") Integer a);
}

在进行请求后,http://127.0.0.1:8000/hystrix/providerPartHystrix,正常返回结果:

{"msg":"Success","code":1000,"data":"port : 7000 --- testPartHystrixSleep : 4 -- a : 1"}

参考:
Feign如何实现局部配置优先于全局默认配置

相关文章

网友评论

    本文标题:feign和hystrix的超时配置总结 以及 Hystrix的

    本文链接:https://www.haomeiwen.com/subject/mvdgaltx.html