Spring Cloud Feign的超时和重试

Feign

Feign在英语中是伪装的意思,这里Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样。

这样我们就不用再自己拼接url,拼接参数等等操作,一切都交给Feign去做。

Feign也是Netflix开发的,是一种声明式、模板化的HTTP客户端,Feign可以让我们更加便捷地调用HTTP API。

Feign支持自带注解或JAX-RS注解。SpringCloud对Feign进行了增强,使Feign支持SpringMVC注解,并整合了Ribbon和Hystrix。

超时

在微服务架构中,一个服务对服务的访问至少得配置一个超时时间,不可能请求一个接口等了好几分钟都还没有返回,在设置超时时间后,超时后就认为这次接口请求失败了。

重试

服务B调用服务A,服务A部署了3台机器,现在服务B通过负载均衡的算法,调用到了服务A的机器1,因为服务A的机器1宕机了,请求超时了,可以让服务B再次请求一次服务A的机器1,如果还是不行,再请求服务A的机器2,如果还是不行,就再请求服务A的服务3,这就是重试机制。

Spring Cloud Feign 的重试机制的演进

在早期的Feign也有重试的模块,但是后来发现和Ribbon冲突了,于是SpringCloud团队在后面的版本将Feign的重试设置为NERVER_RETRY了。因此,对于Camden以及以后的版本,Feign的重试可使用如下属性进行配置:

注意,feign的超时时间优先级更高。

超时和重试源码

超时

如果feign没有配置超时时间,则读取ribbon的配置,否则读取feign的超时配置

FeignLoadBalancer.execute(),发送实际的http请求的时候,就会传入设置的超时参数

重试

Feign的重试

Feign本身也具备重试能力,在早期的Spring Cloud中,Feign使用的是 feign.Retryer.Default#Default() ,重试5次。但Feign整合了Ribbon,Ribbon也有重试的能力,此时,就可能会导致行为的混乱。

Spring Cloud意识到了此问题,因此做了改进,将Feign的重试改为 feign.Retryer#NEVER_RETRY ,如需使用Feign的重试,只需使用Ribbon的重试配置即可。

SynchronousMethodHandler.invoke()方法里面,如果抛了异常的话,也会默认根据Retryer进行重试。

Ribbon的重试

因为SpringCloud的Feign重试默认是NEVER_RETRY,所以主要是靠Ribbon的重试机制。

FeignLoadBalancer.getRequestSpecificRetryHandler()方法中,会读取配置的几个参数:OkToRetryOnAllOperations、MaxAutoRetries、MaxAutoRetriesNextServer

LoadBalancerCommand.submit()方法中,读取RetryHandler中配置的参数,会根据请求的情况,是否报错,是否报异常,进行重试的控制

LoadBalancerCommand包含了大量的重试逻辑,这里是判断是否对同一台机器进行重试

重试都会进入retryPolicy方法,判断是否需要进行重试,然后利用rxjava的retry方法进行重试。

对其他机器进行重试

上面的逻辑是服务宕机的时候的重试逻辑,在超时的时候重试逻辑却是在RetryableFeignLoadBalancer里

0

发表评论

邮箱地址不会被公开。