解决FeignClient重试机制造成的接口幂等性
作者:doinbb 时间:2022-01-25 11:10:35
FeignClient重试机制造成的接口幂等性
Feign源码分析,其实现类在 SynchronousMethodHandler,实现方法是public Object invoke(Object[] argv) ,它的代码分析如下:
1.构造请求数据,将对象转换为json:
RequestTemplate template = buildTemplateFromArgs.create(argv);
2.发送请求进行执行(执行成功会解码响应数据):
executeAndDecode(template, options);
3. 执行请求会有重试机制:
Retryer retryer = this.retryer.clone();
while (true) {
try {
return executeAndDecode(template, options);
} catch (RetryableException e) {
try {
retryer.continueOrPropagate(e);
} catch (RetryableException th) {
Throwable cause = th.getCause();
// 重试结束 或则 不允许重试,则通过抛异常的形式终止
if (propagationPolicy == UNWRAP && cause != null) {
throw cause;
} else {
throw th;
}
}
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
}
continue;
}
}
4. Retryer是重试器,其实现方法有两种
第一种是系统默认实现方式,第二种是可以自定义重试器,一般少用,通过默认实现重试类Default可以看到其构造函数中的重试次数为5。
public Default() {
this(100, SECONDS.toMillis(1), 5);
}
public Default(long period, long maxPeriod, int maxAttempts) {
this.period = period;
this.maxPeriod = maxPeriod;
this.maxAttempts = maxAttempts;
this.attempt = 1;
}
因此解决Feign调用的幂等性问题最简单也就最常用的就是让Feign不重试。
为FeignClient增加请求重试机制
spring cloud通过feign client进行服务之间调用的时候,默认不会进行重试,这样会有一个问题,比如你的服务在滚动升级重启的时候,feign的调用将直接失败,但其实我是滚动重启,重启了一个服务实例,还有另外一个服务实例是可用的,应该允许自动均衡策略重试请求发送到另外一个可用的服务实例上去。
要启用重试机制,首先必须引入spring-retry依赖:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
然后通过注册一个bean:
/**
*
* 注册一个重试Bean
* 默认FeignClient不会进行重试,使用的是{@link feign.Retryer#NEVER_RETRY}
*
* @see FeignClientsConfiguration#feignRetryer()
*/
@Bean
public Retryer feignRetryer() {
return new Retryer.Default();
}
大功告成。
不过还有个前提就是,你的远程调用接口方法的必须是幂等的(比如GET方法认为是幂等的,调用多少次结果都一样,而POST方法有可能有重复提交问题),不然还是不会重试的,因为其他HttpMethod被认为是非幂等的,不能重复执行,因此不能被重试
来源:https://blog.csdn.net/doinbb/article/details/108900836
标签:FeignClient,重试,接口,幂等性
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
关于maven使用过程中无法导入依赖的一些总结
2021-12-16 01:51:20
基于Java实现多线程下载并允许断点续传
2021-07-19 03:05:52
![](https://img.aspxhome.com/file/2023/3/101783_0s.png)
Java编程BigDecimal用法实例分享
2022-05-02 05:40:06
Java基础学习之IO流应用案例详解
2022-09-11 17:04:42
Android View移动的六种方法小结
2023-07-06 02:43:39
winform壁纸工具为图片添加当前月的日历信息
2022-03-05 07:23:01
![](https://img.aspxhome.com/file/2023/8/78178_0s.jpg)
Java的反射机制---动态调用对象的简单方法
2023-08-16 19:23:26
开发工具EesyCode使用方法解析
2023-06-27 13:50:46
![](https://img.aspxhome.com/file/2023/0/84260_0s.png)
Java中Date日期时间类具体使用
2022-04-11 23:18:13
static关键字有何魔法?竟让Spring Boot搞出那么多静态内部类(推荐)
2022-07-03 20:26:29
![](https://img.aspxhome.com/file/2023/9/70269_0s.png)
java 读写Parquet格式的数据的示例代码
2022-09-16 11:09:47
![](https://img.aspxhome.com/file/2023/1/98121_0s.png)
一个JAVA小项目--Web应用自动生成Word
2022-04-30 07:19:56
![](https://img.aspxhome.com/file/2023/4/69134_0s.jpg)
Java实现FTP上传到服务器
2022-10-07 10:28:58
史上最全图文讲解Java泛型
2022-08-23 20:27:47
![](https://img.aspxhome.com/file/2023/4/62834_0s.png)
JFinal实现伪静态的方法
2023-07-17 12:11:37
![](https://img.aspxhome.com/file/2023/0/57630_0s.jpg)
如何使用Java调用Linux系统命令
2021-12-24 20:45:31
Springboot之idea之pom文件图标不对问题
2021-12-31 07:27:32
![](https://img.aspxhome.com/file/2023/0/62520_0s.png)
Springboot使用POI实现导出Excel文件示例
2021-09-22 08:18:31
![](https://img.aspxhome.com/file/2023/8/61398_0s.jpg)
浅谈Java消息队列总结篇(ActiveMQ、RabbitMQ、ZeroMQ、Kafka)
2022-06-13 01:30:40
![](https://img.aspxhome.com/file/2023/8/60698_0s.jpg)
Servlet+JDBC实现登陆功能的小例子(带验证码)
2021-05-29 03:04:25
![](https://img.aspxhome.com/file/2023/7/69897_0s.png)