我有很多情况需要在失败的情况下重试任务n次(有时会使用某种形式的重试前退避逻辑)。通常,如果抛出异常,则应该重试任务以达到最大重试次数。
我可以很容易地写一些东西来做到这一点,但不想重新发明轮子我想知道是否有人可以推荐任何框架。我唯一能找到的是:Ant Retry但我不想直接在我的应用程序中使用Ant任务。
由于
答案 0 :(得分:16)
您可以使用此帖中所述的RetriableTasks
:Retrying Operations in Java。如果你愿意,你可以很容易地改变它的等待算法。
示例代码:
//creates a task which will retry 3 times with an interval of 5 seconds
RetriableTask r = new RetriableTask(3, 5000, new Callable(){
public Object call() throws Exception{
//put your code here
}
});
r.call();
答案 1 :(得分:12)
结帐Failsafe。它是一个简单的零依赖库,用于执行重试,支持同步和异步重试,Java 8集成,事件监听器,与其他异步API的集成等:
RetryPolicy retryPolicy = new RetryPolicy()
.handle(ConnectException.class, SocketException.class);
.withMaxRetries(3);
Connection connection = Failsafe.with(retryPolicy).get(() -> connect());
不容易。
答案 2 :(得分:9)
如果你使用Spring:
//import the necessary classes
import org.springframework.batch.retry.RetryCallback;
import org.springframework.batch.retry.RetryContext;
import org.springframework.batch.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.batch.retry.policy.SimpleRetryPolicy;
import org.springframework.batch.retry.support.RetryTemplate;
...
// create the retry template
final RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(new SimpleRetryPolicy(5));
final ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
backOffPolicy.setInitialInterval(1000L);
template.setBackOffPolicy(backOffPolicy);
// execute the operation using the retry template
template.execute(new RetryCallback<Remote>() {
@Override
public Remote doWithRetry(final RetryContext context) throws Exception {
return (Remote) Naming.lookup("rmi://somehost:2106/MyApp");
}
});
答案 3 :(得分:5)
如果您使用 Spring ,使用Spring Retry库非常简单。
现在,Spring Retry是一个单独的库(早期它是 Spring Batch 的一部分)框架。
Step1:添加弹簧重试依赖项。
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
第2步:在您的类中添加@EnableRetry
注释,其中包含应用或的main()方法到您的@Configuration
类中。
第3步:在您的方法中添加@Retryable
注释,如果出现异常,您可以再次重试/再次调用。
@Retryable(maxAttempts=5,backoff = @Backoff(delay = 3000))
public void retrySomething() throws Exception{
logger.info("printSomething{} is called");
throw new SQLException();
}
此@Retryable
注释将重试/调用retrySomething()
5次(包括第一次失败)。
当前线程将在下次重试之间等待3000毫秒或 3秒。
答案 4 :(得分:3)
我已经有了一个答案,但是三年前我必须补充说,现在我绝对喜欢https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify项目。我来告诉你代码吧。
Dim DBQuery
DBQuery = "Select top 100 l_Name from lessee"
objConnection.Open "Provider=sqloledb.1;Server=TestServer;User Id=User;Password=Test123;Database=DBTest"
objRecordSet.Open DBQuery,objConnection
' Return the Result Set '''
For Each element In ObjRecordset.Fields.Item
Value = objRecordSet.fields.item(element)
MsgBox Value
Next
' Release the Resources '''
objRecordSet.Close
objConnection.Close
Set objConnection = Nothing
Set objRecordSet = Nothing
答案 5 :(得分:1)
将此问题排除在您的代码库之外的一个选项是在应用程序的组件之间使用命令模式。 一旦将业务方法的调用转换为对象,您就可以轻松地处理调用并拥有一个抽象的RetryHandler,它接受命令并重试它。这应该与实际呼叫无关,并且可以重复使用。
答案 6 :(得分:0)
我已经实现了一个非常灵活的重试实用程序here
您可以使用以下命令重试任何Callable:
public static <T> T executeWithRetry(final Callable<T> what, final int nrImmediateRetries,
final int nrTotalRetries, final int retryWaitMillis, final int timeoutMillis,
final Predicate<? super T> retryOnReturnVal, final Predicate<Exception> retryOnException)
立即+延迟重试,最大超时,并根据结果或异常重新决定。
此功能的其他几个版本具有或多或少的灵活性。
我还写了一个可以应用注释的方面Retry Retry Aspect
答案 7 :(得分:-1)