美文网首页
guava-retry

guava-retry

作者: 愤怒的老照 | 来源:发表于2020-06-06 16:29 被阅读0次

    背景

    之前很少接触需要重试的东西,失败后直接抛异常。但是接触过分布式锁以后,未获取锁的异常属于正常现象,需要我们捕获后重试,经过设定的重试次数后如果再抛异常,就直接抛给上层。

    实现1

    第一种方法是直接在代码使用循环来实现重试。

    public void test(RegisterParam registerParam){
            int times  = 3;
            for (int i=0;i<times;i++) {
                try {
                    this.registerWithRetry(registerParam);
                    break;
                } catch (InterruptedException e) {
                    // 重试
                } catch (ServiceException e) {
                    // 重试
                }
            }
        }
    

    正常逻辑和重试逻辑强耦合,重试逻辑非常依赖正常逻辑的执行结果,对正常逻辑预期结果被动重试触发,对于重试根源往往由于逻辑复杂被淹没,可能导致后续运维对于重试逻辑要解决什么问题产生不一致理解。重试正确性难保证而且不利于运维,原因是重试设计依赖正常逻辑异常或重试根源的臆测。

    设计模式实现重试

    上面的一个问题就是正常的逻辑和重试代码强耦合在一起,可以通过命令模式来解耦。将要执行的业务抽象成一个命令,将命令传到Retry里,不需要业务代码关心重试,可以实现解耦。

    Guava-Retry

    guava-retry是guava提供的重试机制,使用起来很简单

    引入pom

    <guava-retry.version>2.0.0</guava-retry.version>
    <dependency>
          <groupId>com.github.rholder</groupId>
          <artifactId>guava-retrying</artifactId>
          <version>${guava-retry.version}</version>
    </dependency>
    

    构造重试对象

    Retryer<Boolean> retryer = RetryerBuilder
                    .<Boolean>newBuilder()
                     // 如果结果是false,重试
                    .retryIfResult(Predicates.equalTo(false))
                     // 本次尝试失败后,过3秒再次尝试
                    .withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS))
                    // 总共尝试3次
                    .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                    // 遇到运行时异常才重试
                    .retryIfRuntimeException()
                    .build();
    

    使用

    retryer.call(() -> this.registerWithRetry(registerParam));
    

    相关文章

      网友评论

          本文标题:guava-retry

          本文链接:https://www.haomeiwen.com/subject/lkoozhtx.html