我在项目中使用过弹簧声明重试,如
@Service
class Service {
@Async @Retryable(maxAttempts=12, backoff=@Backoff(delay=100, maxDelay=500))
public service() {
// ... do something
}
}
现在,我有两个问题。
使用异步重试是否可以,我没有任何问题,只是 我想确定。
第二个要求是,如果进程失败,我想将其记录到日志文件中,包括剩余的重试次数。那么,有没有办法传递,或从方法内部获得剩余重试次数?
答案 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。要使用此功能,客户端只需将回调传递到同一方法”