feign和hystrix的超时配置总结 以及 Hystrix的局部、全局各自的超时配置

#参考官方配置 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如何实现局部配置优先于全局默认配置

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容