Java基于Guava Retrying实现重试功能

 更新时间:2020年07月06日 09:39:27   作者:BarryW  
这篇文章主要介绍了Java基于Guava Retrying实现重试功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

在接口调用中由于各种原因,可能会重置失败的任务,使用Guava-Retrying可以方便的实现重试功能。

首先,需要引用Guava-Retrying的包

<dependency>
  <groupId>com.github.rholder</groupId>
  <artifactId>guava-retrying</artifactId>
  <version>2.0.0</version>
</dependency>

代码示例:

import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.google.common.base.Predicates;

import java.util.concurrent.TimeUnit;

import static com.github.rholder.retry.WaitStrategies.incrementingWait;

/**
 * @author wangxuexing
 * @descrption
 * @date
 */
public class RetryDemo {
  public static void main(String[] args) {
    Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder().
                  //如果异常会重试
                  retryIfException().
                  //如果结果为false会重试
                  retryIfResult(Predicates.equalTo(false)).
                  //重调策略
                  withWaitStrategy(incrementingWait(30, TimeUnit.SECONDS, 30, TimeUnit.SECONDS)).
                  //尝试次数
                  withStopStrategy(StopStrategies.stopAfterAttempt(3)).
                  //注册监听
                  withRetryListener(new MyRetryListener()).build();
    try {
      retryer.call(new TaskCallable());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

其中TaskCallable是任务的具体实现类,它实现了Callable接口

import java.util.concurrent.Callable;

/**
 * @author wangxuexing
 * @descrption
 * @date
 */
public class TaskCallable implements Callable<Boolean> {

  public Boolean call() throws Exception {
    return false;
  }
}

另外,MyRetryListener监听实现了RetryListener接口,每次重试都会回调注册的监听

import com.github.rholder.retry.Attempt;
import com.github.rholder.retry.RetryListener;

/**
 * @author wangxuexing
 * @descrption
 * @date
 */
public class MyRetryListener implements RetryListener {
  public <V> void onRetry(Attempt<V> attempt) {
    System.out.print("[retry]time=" + attempt.getAttemptNumber());
    // 距离第一次重试的延迟
    System.out.print(",delay=" + attempt.getDelaySinceFirstAttempt());

    // 重试结果: 是异常终止, 还是正常返回
    System.out.print(",hasException=" + attempt.hasException());
    System.out.print(",hasResult=" + attempt.hasResult());

    // 是什么原因导致异常
    if (attempt.hasException()) {
      System.out.print(",causeBy=" + attempt.getExceptionCause().toString());
    } else {// 正常返回时的结果
      System.out.print(",result=" + attempt.getResult());
    }
    System.out.println();
  }
}

执行一下main方法,可以看到执行的结果:

[retry]time=1,delay=0,hasException=false,hasResult=true,result=false
[retry]time=2,delay=30000,hasException=false,hasResult=true,result=false
[retry]time=3,delay=90000,hasException=false,hasResult=true,result=false
com.github.rholder.retry.RetryException: Retrying failed to complete successfully after 3 attempts.
at com.github.rholder.retry.Retryer.call(Retryer.java:174)
at test.retryer.RetryDemo.main(RetryDemo.java:32)

下面详细分析一下:

RetryerBuilder是一个factory创建者,可以定制设置重试源且可以支持多个重试源,可以配置重试次数或重试超时时间,以及可以配置等待时间间隔,创建重试者Retryer实例。

  • RetryerBuilder的重试源支持Exception异常对象 和自定义断言对象,通过retryIfException 和retryIfResult设置,同时支持多个且能兼容。
  • retryIfException,抛出runtime异常、checked异常时都会重试,但是抛出error不会重试。
  • retryIfRuntimeException只会在抛runtime异常的时候才重试,checked异常和error都不重试。
  • retryIfExceptionOfType允许我们只在发生特定异常的时候才重试,比如NullPointerException和IllegalStateException都属于runtime异常,也包括自定义的error
  • retryIfResult可以指定你的Callable方法在返回值的时候进行重试

StopStrategy:停止重试策略,提供三种:

StopAfterDelayStrategy 设定一个最长允许的执行时间;比如设定最长执行10s,无论任务执行次数,只要重试的时候超出了最长时间,则任务终止,并返回重试异常RetryException。

NeverStopStrategy 不停止,用于需要一直轮训知道返回期望结果的情况。

StopAfterAttemptStrategy 设定最大重试次数,如果超出最大重试次数则停止重试,并返回重试异常。

  • WaitStrategy:等待时长策略(控制时间间隔),返回结果为下次执行时长:
  • FixedWaitStrategy 固定等待时长策略。
  • RandomWaitStrategy 随机等待时长策略(可以提供一个最小和最大时长,等待时长为其区间随机值)。
  • IncrementingWaitStrategy 递增等待时长策略(提供一个初始值和步长,等待时间随重试次数增加而增加)。
  • ExponentialWaitStrategy 指数等待时长策略。
  • FibonacciWaitStrategy Fibonacci 等待时长策略。
  • ExceptionWaitStrategy 异常时长等待策略。
  • CompositeWaitStrategy 复合时长等待策略。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java实现短信验证码的示例代码

    Java实现短信验证码的示例代码

    Java是一种流行的编程语言,验证码是一种常用的网络安全技术。Java发展至今,网上也出现了各种各样的验证码,下面是用Java实现短信验证码的总结,感兴趣的可以了解一下
    2023-03-03
  • Activiti开发环境的搭建过程详解

    Activiti开发环境的搭建过程详解

    这篇文章主要介绍了Activiti开发环境的搭建过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • SpringCache常用注解及key中参数值为null问题解析

    SpringCache常用注解及key中参数值为null问题解析

    这篇文章主要介绍了SpringCache常用注解及key中参数值为null的问题解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 详解Mybatis中的PooledDataSource

    详解Mybatis中的PooledDataSource

    这篇文章主要介绍了详解Mybatis中的PooledDataSource,PooledDataSource使用了数据库连接池可以实现数据库连接池的重复利用,还能控制连接数据库的连接上限
    2022-06-06
  • Spring MVC处理响应的案例详解

    Spring MVC处理响应的案例详解

    当服务器向客户端响应数据时,SpringMVC框架会使用“转换器”(Converter)将方法的返回值进行转换,SpringMVC框架还会自动使用不同的转换器,因此这篇文章就给大家详细介绍一下Spring MVC如何处理响应并附上案例,需要的朋友可以参考下
    2023-06-06
  • Java switch case数据类型原理解析

    Java switch case数据类型原理解析

    这篇文章主要介绍了Java switch case数据类型原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • SpringBoot3安全管理操作方法

    SpringBoot3安全管理操作方法

    这篇文章主要介绍了SpringBoot3安全管理,在实际开发中,最常用的是登录验证和权限体系两大功能,在登录时完成身份的验证,加载相关信息和角色权限,在访问其他系统资源时,进行权限的验证,保护系统的安全,文中有详细的操作步骤,需要的朋友可以参考下
    2023-08-08
  • MyBatis 多表联合查询及优化方法

    MyBatis 多表联合查询及优化方法

    大家都知道Hibernate 是全自动的数据库持久层框架,它可以通过实体来映射数据库,通过设置一对多、多对一、一对一、多对多的关联来实现联合查询,接下来通过本文给大家介绍MyBatis 多表联合查询及优化,需要的朋友可以参考下
    2022-08-08
  • springboot2中session超时,退到登录页面方式

    springboot2中session超时,退到登录页面方式

    这篇文章主要介绍了springboot2中session超时,退到登录页面方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Java MD5消息摘要算法原理及实现代码

    Java MD5消息摘要算法原理及实现代码

    这篇文章主要介绍了Java MD5消息摘要算法原理及实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论