前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你不得不知的重试神器-Retryer

你不得不知的重试神器-Retryer

作者头像
加多
发布2020-06-16 15:47:59
1.7K0
发布2020-06-16 15:47:59
举报
文章被收录于专栏:Java编程技术Java编程技术

一、前言

好的代码应该具备健壮性,比如代码里面调用了一个http请求,如果当时网络抖了下,http就调用失败了,这时候我们往往需要重试,本文我们就来介绍一个功能比较完善的重试组件-Retryer。

二、Retryer介绍

使用组件需要首先在项目中引入maven依赖:

代码语言:javascript
复制
    <dependency>
      <groupId>com.github.rholder</groupId>
      <artifactId>guava-retrying</artifactId>
      <version>2.0.0</version>
    </dependency>

下面我们通过一个例子,来看如何使用该组件:

代码语言:javascript
复制
// 1.创建重试器对象
    private final static Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
            .retryIfResult(Predicates.<Boolean>isNull())// 1.1当重试的方法返回null时候进行重试
            .retryIfExceptionOfType(IOException.class)// 1.2当重试方法抛出IOException类型异常时候进行重试
            .withStopStrategy(StopStrategies.stopAfterAttempt(3))// 1.3尝试执行三次(也就是重试2次)
            .withWaitStrategy(WaitStrategies.fixedWait(2, TimeUnit.SECONDS))//1.4重试间隔
            .build();

    public static void main(String[] args) {

        // 2需要重试的方法
        Callable<Boolean> callable = new Callable<Boolean>() {
            public Boolean call() throws Exception {

                // dosomthing

                return null; // do something useful here
            }
        };

        // 3.添加需要重试方法到执行器
        try {
            Boolean result = retryer.call(callable);
            System.out.println(result);
        } catch (RetryException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

如上代码1我们创建了一个重试器对象并配置了其重试参数,其中代码1.1我们使用retryIfResult方法设置当重试方法返回值什么时候进行重试,这里我们设置当返回值为null时候进行重试,该方法枚举值有:

  • alwaysTrue() 无论返回值是啥,都进行重试
  • alwaysFalse() 返回值是啥,都不进行重试
  • isNull() 返回值为null,进行重试
  • notNull() 返回值不为null,进行重试
  • not(Predicate<T> predicate) 自己设置谓词表达式,决定返回值为啥时候时候进行重试

代码1.2通过retryIfExceptionOfType方式设置,当重试的方法执行过程中抛出了什么类型的异常后,进行重试。在进行重试时候一般我们不是发生什么错误都进行重试,比如执行数据库插入操作时候,如果发生了主键冲突,则没必要进行重试。

代码1.3设置重试停止策略,一般我们都传递StopStrategies.stopAfterAttempt(3)来设置重试次数,比如我们设置重试方法执行3次(一次正常执行,二次重试),如果还是失败则停止重试。

代码1.4设置重试间隔,通过方法 withWaitStrategy,设置当重试方法执行失败后,下一次重试什么时候开始,一般策略有等待多少时间后,进行下一次重试,常用策略如下:

  • WaitStrategies.fixedWait(2, TimeUnit.SECONDS) 等待固定多少时间进行重试
  • WaitStrategies.incrementingWait(3, TimeUnit.SECONDS,1,TimeUnit.SECONDS) 每次重试等待时间添加个增量
  • WaitStrategies.fibonacciWait(1000,10,TimeUnit.SECONDS) 斐波那契数列方式设置重试间隔。

如上代码2我们创建了一个需要重试的任务,代码3添加需要重试方法到执行器。最后Retryer是线程安全的?也就是整个JVM内我创建了一个retryer实例,多线程同时向retryer里面添加重试任务,会存在问题?

答案是,不存在问题,其是线程安全的。这是因为Retryer内部与重试相关的变量是在第一次添加任务时候,通过new了与任务相关的ResultAttempt进行隔离了,每个重试任务有自己的ResultAttempt变量来记录重试信息。

组件开源地址:https://github.com/rholder/guava-retrying

三、总结

工具用的6,可以提高工作效率;另一方面好的开源组件,代码质量还是比较高的,可以学习期设计思想与代码实现;最后使用开源组件相比自己手写也可以提高稳定性^^。一句话:善用工具,会起到事半功倍的效果。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、Retryer介绍
  • 三、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档