SpringBoot重试,重试

时间:2017-08-01 10:13:59

标签: java spring spring-boot spring-retry

我在项目中使用过弹簧声明重试,如

@Service
class Service {
  @Async  @Retryable(maxAttempts=12, backoff=@Backoff(delay=100, maxDelay=500))
    public service() {
        // ... do something
    }
}

现在,我有两个问题。

  1. 使用异步重试是否可以,我没有任何问题,只是 我想确定。

  2. 第二个要求是,如果进程失败,我想将其记录到日志文件中,包括剩余的重试次数。那么,有没有办法传递,或从方法内部获得剩余重试次数?

2 个答案:

答案 0 :(得分:3)

您应该使用@Recover注释对每个失败执行操作,并在方法之外的对象内部保持计数。确保没有其他方法与此计数器交互。这是基本前提:

@Service
class Service {


private int attemptsLeft=12;

@Retryable(maxAttempts=12, backoff=@Backoff(delay=100, maxDelay=500))
public service() {
    // ... do something that throws a KnownException you create to catch later on.
}

@Recover
public void connectionException(KnownException e) {
            this.attemptsLeft = this.attemptsLeft-1; //decrease your failure counter
            Logger.warn("Retry attempts left:{}",attemptsLeft);
        }
}

如果您不想要成员变量跟踪计数,您可能需要抛弃注释并使用RetryTemplate方法声明getRetryCount()以访问上下文。

public String serviceWithRetry() {
    RetryTemplate retryTemplate = new RetryTemplate();
    final SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
    retryPolicy.setMaxAttempts(12);
    retryTemplate.setRetryPolicy(retryPolicy);
    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
    backOffPolicy.setInterval(100L);
    retryTemplate.setBackOffPolicy(backOffPolicy);
    retryTemplate.execute(new RetryCallback<Void, RuntimeException>() 
        return retryTemplate.execute(new RetryCallback<Void, RuntimeException>() {
        @Override
        public void doWithRetry(RetryContext context) {
            LOG.info("Retry of connection count: {}", context.getRetryCount());
            return //something with your connection logic
        }
    });
}

答案 1 :(得分:3)

无法使用注释,@ Recover带注释的方法仅在最后一次失败的重试后执行,而不是在每次失败后执行。

Refer to this github documentation

以上链接的摘录 - “调用”服务“方法,如果失败并显示RemoteAccessException,则会重试(默认情况下最多三次),然后执行”recover“方法,如果不成功。”< / p>

即使使用RetryTemplate,只有在所有重试都用尽后才会调用重试回调。

另一个摘录形成相同的链接 - “当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即RecoveryCallback。要使用此功能,客户端只需将回调传递到同一方法”