- 1 guava-retry的简介
- 2 guava-retry的使用
- 1 导入maven依赖
- 2 添加一个重试方法
- 3 添加测试类
- 3 总结
官网地址:
https://github.com/rholder/guava-retrying
https://codechina.csdn.net/mirrors/rholder/guava-retrying?utm_source=csdn_github_accelerator
1 guava-retry的简介在日常的一些场景中, 很多需要进行重试的 *** 作.查询资料Guava-Retry工具对于重试 *** 作效果比较好.
Guava retryer是一个基于Guava,提供重试机制的库,是通过定义重试者角色来包装正常逻辑重试,支持重试次数和重试频度控制,能够兼容支持多个异常或者自定义实体对象的重试源定义,让重试功能有更多的灵活性, 而且也是线程安全的,入口调用逻辑采用的是java.util.concurrent.Callable的call方法.
2 guava-retry的使用 1 导入maven依赖2 添加一个重试方法com.github.rholder guava-retrying2.0.0
@Slf4j public class RetryDemo { public static boolean retryMethod(Integer param) { int i = new Random().nextInt(param); log.info("随机生成的数:{}", i); if (1 == i) { log.info("为1,返回true."); return true; } else if (i < 1) { log.info("小于1,抛出参数异常."); throw new IllegalArgumentException("参数异常"); } else if (i > 1 && i < 10) { log.info("大于1,小于10,抛出参数异常."); return false; } else { //为其他 log.info("大于10,抛出自定义异常."); throw new RemoteAccessException("大于10,抛出自定义异常"); } } }3 添加测试类
@Slf4j public class GuavaRetryTest { public static void main(String[] args) { Boolean result = false; // RetryerBuilder 构建重试实例对象 // 1 可以设置重试源且可以支持多个重试源 // 2 可以设置根据结果重试 // 3 可以配置等待时间间隔 // 4 可以配置重试次数或重试超时时间 Retryerretryer = RetryerBuilder. newBuilder() .retryIfExceptionOfType(RemoteAccessException.class)//设置异常重试源 .retryIfException() .retryIfResult(res -> false) //设置根据结果重试 .withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS)) //设置等待间隔时间 .withStopStrategy(StopStrategies.stopAfterAttempt(3)) //设置最大重试次数 .withRetryListener(new RetryListener() { @Override public void onRetry(Attempt attempt) { log.info("第【{}】次调用失败", attempt.getAttemptNumber()); } }) .build(); try { result = retryer.call(new Callable () { @Override public Boolean call() throws Exception { return RetryDemo.retryMethod(110); } }); // 上述可以简化为 // result = retryer.call(() -> RetryDemo.retryMethod(110)); } catch (Exception e) { e.printStackTrace(); log.info("超时三次错误,{}", e.getMessage()); } System.out.println("方法调用返回状态= " + result); } }
说明:
RetryerBuilder类是一个工厂建造者,可以设置多个重试源,可以设置重试次数和重试超时时间等,创建重试者Retryer对象.
RetryerBuilder部分源码:
public class RetryerBuilder{ // 单次任务执行时间限制 private AttemptTimeLimiter attemptTimeLimiter; // 停止策略 private StopStrategy stopStrategy; // 等待策略 private WaitStrategy waitStrategy; // 阻塞策略 private BlockStrategy blockStrategy; // 重试源 支持Exception异常对象和自定义断言对象 private Predicate> rejectionPredicate = Predicates.alwaysFalse(); // 重试监听 private List listeners = new ArrayList (); private RetryerBuilder() { } // new一个RetryerBuilder对象 public static RetryerBuilder newBuilder() { return new RetryerBuilder (); } // 创建一个Retryer对象 public Retryer build() { AttemptTimeLimiter theAttemptTimeLimiter = attemptTimeLimiter == null ? AttemptTimeLimiters. noTimeLimit() : attemptTimeLimiter; StopStrategy theStopStrategy = stopStrategy == null ? StopStrategies.neverStop() : stopStrategy; WaitStrategy theWaitStrategy = waitStrategy == null ? WaitStrategies.noWait() : waitStrategy; BlockStrategy theBlockStrategy = blockStrategy == null ? BlockStrategies.threadSleepStrategy() : blockStrategy; return new Retryer (theAttemptTimeLimiter, theStopStrategy, theWaitStrategy, theBlockStrategy, rejectionPredicate, listeners); } // ... }
Retryer部分源码:
public final class Retryer3 总结{ // 停止策略 private final StopStrategy stopStrategy; // 等待策略 private final WaitStrategy waitStrategy; // 阻塞策略 private final BlockStrategy blockStrategy; // 单次任务执行时间限制 private final AttemptTimeLimiter attemptTimeLimiter; // 重试源 支持Exception异常对象和自定义断言对象 private final Predicate> rejectionPredicate; // 重试监听 private final Collection listeners; // RetryerBuilder建造者中build方法被使用 @Beta public Retryer(@Nonnull AttemptTimeLimiter attemptTimeLimiter, @Nonnull StopStrategy stopStrategy, @Nonnull WaitStrategy waitStrategy, @Nonnull BlockStrategy blockStrategy, @Nonnull Predicate> rejectionPredicate, @Nonnull Collection listeners) { Preconditions.checkNotNull(attemptTimeLimiter, "timeLimiter may not be null"); Preconditions.checkNotNull(stopStrategy, "stopStrategy may not be null"); Preconditions.checkNotNull(waitStrategy, "waitStrategy may not be null"); Preconditions.checkNotNull(blockStrategy, "blockStrategy may not be null"); Preconditions.checkNotNull(rejectionPredicate, "rejectionPredicate may not be null"); Preconditions.checkNotNull(listeners, "listeners may not null"); this.attemptTimeLimiter = attemptTimeLimiter; this.stopStrategy = stopStrategy; this.waitStrategy = waitStrategy; this.blockStrategy = blockStrategy; this.rejectionPredicate = rejectionPredicate; this.listeners = listeners; } // 线程安全调用重试方法 public V call(Callable callable) throws ExecutionException, RetryException { long startTime = System.nanoTime(); for (int attemptNumber = 1; ; attemptNumber++) { Attempt attempt; try { V result = attemptTimeLimiter.call(callable); attempt = new ResultAttempt (result, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)); } catch (Throwable t) { attempt = new ExceptionAttempt (t, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)); } for (RetryListener listener : listeners) { listener.onRetry(attempt); } if (!rejectionPredicate.apply(attempt)) { return attempt.get(); } if (stopStrategy.shouldStop(attempt)) { throw new RetryException(attemptNumber, attempt); } else { long sleepTime = waitStrategy.computeSleepTime(attempt); try { blockStrategy.block(sleepTime); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RetryException(attemptNumber, attempt); } } } } }
Guava-Retry, 是一个非常灵活简单上手的工具. 可以完好的把重试功能和业务逻辑解耦, 不但支持多种设置, 如多异常判断,重试次数,重试时间,以及每次重试方法时的监听.并且是属于线程安全的, 在并发的场景下也能稳定支持.
参考资料:
https://blog.csdn.net/zzzgd_666/article/details/84377962
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)