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

 更新时间:2021年07月05日 10:57:36   作者:doinbb  
这篇文章主要介绍了解决FeignClient重试机制造成的接口幂等性问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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被认为是非幂等的,不能重复执行,因此不能被重试

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mybatis中关于type-aliases-package的使用

    mybatis中关于type-aliases-package的使用

    这篇文章主要介绍了mybatis中关于type-aliases-package的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • java小程序火锅店点餐系统

    java小程序火锅店点餐系统

    这篇文章主要介绍了java小程序火锅店点餐系统,采用Java语言和Vue技术,以小程序模式实现的火锅点菜系统,文中提供了解决思路和部分实现代码,需要的朋友可以参考下
    2023-03-03
  • MyBatis使用级联操作解决lombok构造方法识别失败问题

    MyBatis使用级联操作解决lombok构造方法识别失败问题

    这篇文章主要介绍了MyBatis使用级联操作解决lombok构造方法识别失败问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Ubuntu16.04 64位下JDK1.7的安装教程

    Ubuntu16.04 64位下JDK1.7的安装教程

    这篇文章主要为大家详细介绍了Ubuntu16.04 64位下JDK1.7的安装教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • Java OpenCV图像处理之自定义图像滤波算子

    Java OpenCV图像处理之自定义图像滤波算子

    这篇文章主要为大家介绍了如何利用Java OpenCV实现自定义图像滤波(降噪) 算子,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编学习一下
    2022-02-02
  • mybatis中返回主键一直为1的问题

    mybatis中返回主键一直为1的问题

    这篇文章主要介绍了mybatis中返回主键一直为1的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • java生成验证码图片的方法

    java生成验证码图片的方法

    这篇文章主要为大家详细介绍了java生成验证码图片的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-02-02
  • java实现清理DNS Cache的方法

    java实现清理DNS Cache的方法

    这篇文章主要介绍了java实现清理DNS Cache的方法,分析了几种常用的清理方法,并给出了反射清理的完整实例,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • Java实现多级表头和复杂表头的导出功能

    Java实现多级表头和复杂表头的导出功能

    这篇文章主要为大家详细介绍了Java实现多级表头和复杂表头的导出功能的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • Mybatis-plus操作json字段实战教程

    Mybatis-plus操作json字段实战教程

    这篇文章主要介绍了Mybatis-plus操作json字段实战教程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-02-02

最新评论