最近自己在写一套SpringCloud的全家桶项目,发现一个问题,很是让人头疼,就是超时的设置问题,先来介绍下我的实践场景:
网关: SpringCloud Gateway
请求路径: 前端->网关->服务A->服务B
问题:
在服务A进行断点debugger测试,结果直接接口直接被网关降级返回:服务A暂不可用,但是实际情况就是,我只是在服务A处打了断点进行调试而已,所有服务其实都是正常运行的,只是网关急不可耐的对服务A的调用提前判了死刑,也就是服务降级,尝试多次后,直接会触发熔断。
我的网关,是启用了Hystrix的限流以及服务降级还有熔断功能,这个时候,我就想到超时时间的设置,但是又想到,网关还使用了Ribbon的负载均衡,这个其实也是有超时时长的,然后,在服务A和服务B中的话,还存在Feign这种客户端请求工具,也是有超时时长的限制,那么这个时候,就需要去好好梳理,各种工具的超时设置的关系了,不然,这种问题调测起来,是非常费力气的。
Ribbon:服务负载均衡工具
Hystrix:服务调用触发降级、熔断工具
Feign:客户端请求工具【Ribbon+Hystrix】
关系:Hystrix和Ribbon一起读秒,Feign是他们两者时间总和;
一般情况下 都是 ribbon 的超时时间(<)hystrix的超时时间(否则会在接口调用还未完成的时候直接进入回调方法),但是我自己是不再去单独设置Ribbon的超时、重试的,因为Ribbon的作用就是帮助我们寻找服务,而服务这一块在注册中心管理,如果找不到服务,大概率是服务没有注册或者有问题,我更喜欢让他快速失败,对于它的超时和重试设置,不是很有必要,反而会加大问题排查难度。
再来说一下Feign,因为ribbon的重试机制和Feign的重试机制有冲突,所以源码中默认关闭Feign的重试机制,对于我自己而已,也不希望它开启重试,快速失败反而直观。
设置Hystrix的超时,则是因为,业务处理是需要一定时间的,而且我不希望在我还没有处理完业务的时候,就被迫返回、触发降级甚至熔断,这是不合理的。
设置Hystrix超时、重试、熔断的配置流程
1.启用注解开启对Hystrix的支持
2.yaml或者接口定义中设置超时
如果是网关的话
# hystrix相关配置
hystrix:
command:
default:
execution: ## 超时配置
isolation:
thread:
timeoutInMilliseconds: 20000 #设置请求超时时间,默认1秒,超过指定的时间后,触发降级
circuitBreaker: ##熔断配置
requestVolumeThreshold: 3 #达到指定的次数后熔断服务 (默认20次)
sleepWindowInMilliseconds: 5000 #熔断后,多长时间进行恢复(默认 5000)
如果是服务A、B、C的话还需要开启Feign的Hystrix支持
# 开启Feign熔断器配置
feign:
hystrix:
enabled: true