app开发者平台在数字化时代的重要性与发展趋势解析
1487
2022-12-31
解决FeignClient重试机制造成的接口幂等性
FeignClient重试机制造成的接口幂等性
Feign源码分析,其实现类在 SynchronousMethodHandler,实现方法是public Object invoke(Object[] ahttp://rgv) ,它的代码分析如下:
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>
然后通过注册一个bean:
/**
*
* 注册一个重试Bean
* 默认FeignClient不会进行重试,使用的是{@link feign.Retryer#NEVER_RETRY}
*
* @see FeignClientsConfiguration#feignRetryer()
*/
@Bean
public Retryer feignRetryer() {
return new Retryer.Default();
}
大功告成。
不过还有个前提就是,你的远程调用接口方法的必须是幂等的(比如GET方法认为是幂等的,调用多少次结果都一样,而POST方法有可能有重复提交问题),不然还是不会重试的,因为其他HttpMethod被认为是非幂等的,不能重复执行,因此不能被重试
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~