重试任务框架
我有很多情况需要在失败的情况下重试任务n次(有时会使用某种forms的重试前退避逻辑)。 通常,如果抛出exception,则应该重试任务以达到最大重试次数。
我可以很容易地写一些东西来做这个相当一般,但不想重新发明轮子我想知道是否有人可以推荐任何框架。 我唯一能找到的是: Ant Retry但我不想直接在我的应用程序中使用Ant任务。
谢谢
您可以使用RetriableTasks
中概述的RetriableTasks
: 在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();
查看故障保险 。 它是一个简单的零依赖库,用于执行重试,支持同步和异步重试,Java 8集成,事件监听器,与其他异步API的集成等:
RetryPolicy retryPolicy = new RetryPolicy() .retryOn(ConnectException.class, SocketException.class); .withMaxRetries(3); Connection connection = Failsafe.with(retryPolicy).get(() -> connect());
没有变得容易。
如果你使用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() { @Override public Remote doWithRetry(final RetryContext context) throws Exception { return (Remote) Naming.lookup("rmi://somehost:2106/MyApp"); } });
原创博文
如果您使用的是Spring ,那么使用Spring Retry Library 非常简单 。
现在,Spring Retry是一个单独的库( 早期它是Spring Batch的一部分)框架。
第1步:添加弹簧重试依赖项。
org.springframework.retry spring-retry 1.1.2.RELEASE
第2 @EnableRetry
:将@EnableRetry
注释添加到您的类中,该类包含应用程序的main()方法或任何@Configuration
类。
步骤3:在exception情况下,将@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 ms或3秒 。
我已经有了一个答案,但是三年前我必须补充说,现在我绝对喜欢番石榴重试项目。 我来告诉你代码吧。
Callable callable = new Callable () { public Boolean call() throws Exception { return true; // do something useful here } }; Retryer retryer = RetryerBuilder. newBuilder() .retryIfResult(Predicates. isNull()) .retryIfExceptionOfType(IOException.class) .retryIfRuntimeException() .withStopStrategy(StopStrategies.stopAfterAttempt(3)) .build(); try { retryer.call(callable); } catch (RetryException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }
将此问题排除在代码库之外的一个选择是在应用程序的组件之间使用命令模式。 一旦将业务方法的调用转换为对象,就可以轻松地处理调用并拥有一个抽象的RetryHandler,它接受命令并重试它。 这应该独立于实际调用和可重用。
你可以使用Quartz 。 看看这个 Stack Overflow答案。
我在这里实现了一个非常灵活的重试实用程序
您可以使用以下命令重试任何Callable:
public static T executeWithRetry(final Callable what, final int nrImmediateRetries, final int nrTotalRetries, final int retryWaitMillis, final int timeoutMillis, final Predicate super T> retryOnReturnVal, final Predicate retryOnException)
具有立即+延迟重试,具有最大超时,并根据结果或exception进行重试。
此function还有其他几个版本,具有或多或少的灵活性。
我还写了一个方面,可以应用注释重 试 重 试方面