1.什么是Feign超时
1.使用Feign调用接口分为两层,Ribbon的调用和Hystrix的调用,所以Ribbon的超时时间和Hystrix的超时时间的结合就是Feign的超时时间。
2.一般情况下 都是 Ribbon 的超时时间(<)Hystrix的超时时间(因为涉及到Ribbon 的重试机制),如果Ribbon 的超时时间大于Hystrix的超时时间,对于Ribbon 的重试是没有意义的(Hystrix超时熔断了,Ribbon 无法重试)。
需要架构源码的朋友可以看我个人简介联系我
提示:
默认情况下,如果Ribbon没有配置重试时间和次数,默认是1S超时,默认会自动重试1次。
默认情况下,如果Hystrix没有配置重试时间和次数,默认是1S超时,默认会自动重试1次。
2.Ribbon超时
问题: 在服务提供者的接口上加休眠5秒,测试Feign调用的时候是否会超时?
接口提供方和接口调用方的application.yml都是如下:
访问接口:http://localhost:8777/getProduct/100 控制台异常如下:
分析: 出现这个异常的时候,起初我不知道究竟是Hystrix断路器走熔断了还是Ribbon处理请求超时了,通过观察日志和做测试,我发现了错误日志是由: org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer包打印出来的,那么我就很确定这是Ribbon处理请求超时了,因为我设置了接口提供方休眠5秒,而Ribbon的默认超时是1秒,而默认情况下在使用Feign时,Hystrix默认是未开启的,这样就更加肯定这是Ribbon超时,那么如何处理呢,见后文。
解决: 服务调用方application.yml加入Ribbon请求处理超时和连接超时,这里需要注意一下,我们在服务提供方的接口里设置休眠的时间是5秒,所以这里在设置Ribbon的超时时间时,需要大于5秒,不然起不到作用。
再次请求:http://localhost:8777/getProduct/100
正如我们初步的判断,上述异常在Feign消费服务,Feign中的Hystrix默认是未开启的,所以这个问题是由Ribbon超时引起的。
3.Hystrix超时
问题: 在服务提供者的接口上加休眠5秒,测试Feign调用的时候是否会超时?
接口提供方的application.yml配置改成如下,为了探究Hystrix我们去掉Ribbon的超时配置,开启Feign中的Hystrix:
访问接口:http://localhost:8777/getProduct/100 控制台异常如下:
控制台打印日志:
分析: 从异常的日志来看,服务调用超时了,超时后Hystrix立即进行了服务的熔断,走了回调方法OrderFeignFallbackFactory,输出了服务熔断后我们定制的Msg,那么如何解决这个超时问题呢?
解决: 在接口调用方application.yml加入Hystrix超时配置,同样这里需要注意的是,Hystrix默认的超时时间是1秒,而我们在服务提供方的接口里设置休眠的时间是5秒,所以这里在设置Hystrix的超时时间时,需要大于5秒,不然起不到作用防止超时的作用。
再次访问接口:http://localhost:8777/getProduct/100 控制台异常如下:
控制台异常如下:
分析: 开启了Hystrix断路器并且设置了Hystrix的超时时间为6秒,但是这个时候Ribbon处理请求却超时了。分析下面这行异常日志:RetryableException 大概意思是重试异常,查阅资料得知,Ribbon在超时后会进行重试的,因为没有对Ribbon超时进行处理,但是开启了Hystirx的断路器功能和设置其超时,所以Ribbon在处理请求超时的时候,Hystirx就出来起作用了,对服务进行熔断,降级处理,进而进入回调方法OrderFeignFallbackFactory,返回友好提示起到服务保护作用。
总结: 通过上述分析,那么在开启Hystrix断路器功能之后就需要对Ribbon进行超时设置了,两者在碰到Feign时,需要协同作战,或者更粗暴点直接不开启Hystrix断路器功能,但是这种方式极不推荐,高并发的项目中服务保护必不可少,所以我们需要将Ribbon与Hystrix结合使用,那么接下来我们需要着重讨论Ribbon与Hystrix如何协同作战。
4.在Feign中禁用Hystrix
禁用Hystrix:
参考官网资料: https://cloud.spring.io/spring-cloud-static/spring-cloud-openfeign/2.2.2.RELEASE/reference/html/#spring-cloud-feign-hystrix
要基于每个客户端禁用Hystrix支持,请创建Feign.Builder具有“原型”范围的香草,这段话摘自官网,例如:
5.同时设置Ribbon超时和Hystrix超时
Feign调用时同时设置Ribbon超时和Hystrix超时,application.yml配置如下
server: port: 8777 spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 enabled: true application: name: nacos-order feign: hystrix: enabled: true hystrix: command: default: execution: timeout: enabled: true isolation: thread: timeoutInMilliseconds: 120000 ribbon: ReadTimeout: 6000 ConnectTimeout: 5000
访问接口: http://localhost:8777/getProduct/100
7.Ribbon超时值和Hystrix超时值如何设定?
注意: Ribbon超时+Hystrix超时= Feign超时
7.1.Feign超时结论
使用Feign调用接口分两层,ribbon的调用和hystrix的调用,所以ribbon的超时时间和Hystrix的超时时间的结合就是Feign的超时时间
一般情况下 都是 ribbon的超时时间(<)hystrix的超时时间(因为涉及到ribbon的重试机制),如果ribbon的超时时间大于hystrix的超时时间,对于ribbon的重试是没有意义的(hystrix超时熔断了,ribbon无法重试),默认我项目中是没有配置ribbon的重试的,但是需要注意的是无论是否需要配置ribbon超时时的重试次数,hystrix的超时都是需要大于ribbon的超时。
7.2.ribbon的重试机制
为了确保重试机制的正常运作,理论上(以实际情况为准)建议hystrix的超时时间为:(1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout
如果配置ribbon的重试,hystrix的超时时间要大于ribbon的超时时间,ribbon才会重试
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70006413/viewspace-2846399/ ,如需转载,请注明出处,否则将追究法律责任。