服务器之家

服务器之家 > 正文

解决FeignClient重试机制造成的接口幂等性

时间:2021-09-26 11:58     来源/作者:doinbb

FeignClient重试机制造成的接口幂等性

Feign源码分析,其实现类在 SynchronousMethodHandler,实现方法是public Object invoke(Object[] argv) ,它的代码分析如下:

1.构造请求数据,将对象转换为json:

?
1
RequestTemplate template = buildTemplateFromArgs.create(argv);

2.发送请求进行执行(执行成功会解码响应数据):

?
1
executeAndDecode(template, options);

3. 执行请求会有重试机制:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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。

?
1
2
3
4
5
6
7
8
9
10
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依赖:

?
1
2
3
4
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

然后通过注册一个bean:

?
1
2
3
4
5
6
7
8
9
10
11
/**
   *
   * 注册一个重试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

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部