记一次Ribbon重试配置不生效问题

记一次Ribbon重试配置不生效问题

问题发生:

生产环境发现一个交易订单对应两个支付订单记录(按实际业务应该一对一)

问题排查:

业务服务在调用支付服务时候是使用Feign来调用接口的(只接收post请求),配置中有重试相关配置(配置如下),由于网络原因,支付服务在10s后没有返回响应,触发了重试机制,导致出现了两个支付订单的情况。

Ribbon重试配置
1
2
3
4
5
6
7
spring.cloud.loadbalancer.retry.enabled = true

ribbon.ReadTimeout = 10000
ribbon.ConnectTimeout = 10000
ribbon.MaxAutoRetries = 1
ribbon.MaxAutoRetriesNextServer = 1
ribbon.OkToRetryOnAllOperations = false

问题模拟:

retry.enabledMaxAutoRetriesMaxAutoRetriesOkToRetryOnAllOperations实验结果
false11true重试4次后,抛出SocketTimeoutException异常
false11false重试4次后,抛出SocketTimeoutException异常
true21false重试6次后,抛出SocketTimeoutException异常
true22false重试9次后,抛出SocketTimeoutException异常
true11true重试4次后,抛出SocketTimeoutException异常

问题分析

从上面的模拟结果可以看两点问题(第3点没在表格列出来):

1、spring.cloud.loadbalancer.retry.enabledribbon.OkToRetryOnAllOperations 两个参数不管配置成 true 还是 false。都会进行重试。

2、ribbon.MaxAutoRetriesribbon.MaxAutoRetriesNextServer 参数改变,会改变重试的次数。

3、ribbon.ReadTimeout 的改变会影响重试间隔时间(这个没在表格中列出来,但是确实会影响)。

问题解决:

查阅了一些资料,以及在网上找了很多博客对spring cloud重试机制的讲解,发现配置并没有问题,所以问题应该不在配置上。

又经过一番对比,发现很多文章包括spring官方文档都有说到,需要引入spring-retry依赖,于是查看项目依赖,果然没有引入该依赖,把依赖引入后问题得到解决。

总结与思考

许多问题的解决方法往往就在眼前,但是时常会被忽略。同时也具有一定的迷惑性,在解决这个问题的过程中,首先因为配置的关系,部分配置是生效的,另一部分没生效,所以会让人搞不清楚是哪里出现的问题。另外,网上找了些文章,里面有说道spring.cloud.loadbalancer.retry.enabled配置默认是关闭的,也就是false,但是我在查阅源码的时候发现,源码(源码如下)里面默认是true,这也让我有点迷惑。所以一开始对引入spring-retry依赖的问题也就忽略了,想着是不是版本更新后这个默认就不需要引入了,也因此陷入了这样一个误区,在兜兜转转一圈后才发现问题所在。

LoadBalancerRetryProperties源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@ConfigurationProperties("spring.cloud.loadbalancer.retry")
public class LoadBalancerRetryProperties {
private boolean enabled = true;

public LoadBalancerRetryProperties() {
}

public boolean isEnabled() {
return this.enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

参考资料

1、https://cloud.spring.io/spring-cloud-netflix/multi/multi_retrying-failed-requests.html

2、https://blog.didispace.com/spring-cloud-ribbon-failed-retry/

3、https://www.liujiajia.me/2019/1/22/feign-retry

4、https://xiefayang.com/2019/04/26/Ribbon——超时与重试/

5、http://www.itmuch.com/spring-cloud-sum/spring-cloud-retry/

6、http://www.itmuch.com/spring-cloud-sum/spring-cloud-timeout/

记一次Ribbon重试配置不生效问题

https://trainoo.gitee.io/2021/04/09/ribbon-retry-problem/

作者

Trainoo

发布于

2021-04-09

更新于

2021-04-12

许可协议