“重试”逻辑失败的devise模式?
我正在写一些重新连接逻辑,以定期尝试build立连接到一个远程端点的故障。 本质上,代码如下所示:
public void establishConnection() { try { this.connection = newConnection(); } catch (IOException e) { // connection failed, try again. try { Thread.sleep(1000); } catch (InterruptedException e) {}; establishConnection(); } }
我已经在很多场合用类似于上面的代码解决了这个普遍的问题,但是我对结果很不满意。 有没有devise模式来处理这个问题?
一个值得检查的库是Sarge ,它根据定义的计划自动执行重试。
无耻的插件:我已经实现了一些类来允许重试操作。 图书馆尚未提供,但你可以在github上分发 。 而叉子存在。
它允许构build一个具有各种灵活策略的重试器。 例如:
Retryer retryer = RetryerBuilder.newBuilder() .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECOND)) .withStopStrategy(StopStrategies.stopAfterAttempt(3)) .retryIfExceptionOfType(IOException.class) .build();
然后你可以用Retryer执行一个可调用的(或几个):
retryer.call(new Callable<Void>() { public Void call() throws IOException { connection = newConnection(); return null; } }
你可以试试幂等重试模式 。
我正在使用AOP和Java注释。 jcabi方面有一个现成的机制(我是开发者):
@RetryOnFailure(attempts = 3, delay = 1, unit = TimeUnit.SECONDS) public void establishConnection() { this.connection = newConnection(); }
PS。 您也可以尝试从Cactoos的RetryScalar 。
使用Failsafe (作者在这里):
RetryPolicy retryPolicy = new RetryPolicy() .retryOn(IOException.class) .withMaxRetries(5) .withDelay(1, TimeUnit.SECONDS); Failsafe.with(retryPolicy).run(() -> newConnection());
没有注释,没有魔法,不需要成为一个spring的应用程序等。只是简单明了。
根本没有什么特别的重试 – 以这个类为例http://www.docjar.com/html/api/org/springframework/jms/listener/DefaultMessageListenerContainer.java.html正如你可以看到,即使是spring的开发者仍然写作代码重试; – 行791 …没有这样的特殊模式AFAIK ..
我可以build议处理资源是采取Apache公共资源库库 – 检查这个http://commons.apache.org/pool/apidocs/org/apache/commons/pool/impl/GenericObjectPool.html和访问http:/ / /commons.apache.org/pool
你可以尝试春季重试 ,它有一个干净的界面,它很容易使用。
例:
@Retryable(maxAttempts = 4, backoff = @Backoff(delay = 500)) public void establishConnection() { this.connection = newConnection(); }
如果出现exception情况,将会重试(调用)最多4次方法establishConnection() ,退避策略为500ms
这可能是这样的;
try { // logic } re-try { // retry logic } re-re-try { // reretry logic } catch(Exception ex) { // log }