Naf*_*Kay 52 java io design-patterns
我正在编写一些重新连接逻辑,以定期尝试建立与远程端点的连接.从本质上讲,代码如下所示:
public void establishConnection() {
try {
this.connection = newConnection();
} catch (IOException e) {
// connection failed, try again.
try { Thread.sleep(1000); } catch (InterruptedException e) {};
establishConnection();
}
}
Run Code Online (Sandbox Code Playgroud)
我已经在很多场合用类似上面的代码解决了这个一般问题,但我对结果感到很不满意.是否有设计模式来处理这个问题?
JB *_*zet 30
无耻的插件:我已经实现了一些类来允许重试操作. 该库尚未提供,但您可以在github上进行分叉.和叉子的存在.
它允许使用各种灵活的策略构建Retryer.例如:
Retryer retryer =
RetryerBuilder.newBuilder()
.withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECOND))
.withStopStrategy(StopStrategies.stopAfterAttempt(3))
.retryIfExceptionOfType(IOException.class)
.build();
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用重试程序执行可调用(或多个):
retryer.call(new Callable<Void>() {
public Void call() throws IOException {
connection = newConnection();
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
yeg*_*256 10
我正在使用AOP和Java注释.在jcabi-aspects中有一个现成的机制(我是开发人员):
@RetryOnFailure(attempts = 3, delay = 1, unit = TimeUnit.SECONDS)
public void establishConnection() {
this.connection = newConnection();
}
Run Code Online (Sandbox Code Playgroud)
PS.您也可以尝试RetryScalar
使用Cactoos.
使用故障安全(作者在这里):
RetryPolicy retryPolicy = new RetryPolicy()
.retryOn(IOException.class)
.withMaxRetries(5)
.withDelay(1, TimeUnit.SECONDS);
Failsafe.with(retryPolicy).run(() -> newConnection());
Run Code Online (Sandbox Code Playgroud)
没有注释,没有魔法,不需要成为Spring应用程序,等等。简单明了。
您可以尝试spring-retry,它具有干净的界面并且易于使用。
例子:
@Retryable(maxAttempts = 4, backoff = @Backoff(delay = 500))
public void establishConnection() {
this.connection = newConnection();
}
Run Code Online (Sandbox Code Playgroud)
在异常情况下,它将重试(调用)最多 4 次方法建立连接(),退避策略为 500 毫秒
我真的很喜欢此博客中的 Java 8代码,并且您的类路径上不需要任何额外的库。
您只需要将一个函数传递给retry类。
@Slf4j
public class RetryCommand<T> {
private int maxRetries;
RetryCommand(int maxRetries)
{
this.maxRetries = maxRetries;
}
// Takes a function and executes it, if fails, passes the function to the retry command
public T run(Supplier<T> function) {
try {
return function.get();
} catch (Exception e) {
log.error("FAILED - Command failed, will be retried " + maxRetries + " times.");
return retry(function);
}
}
private T retry(Supplier<T> function) throws RuntimeException {
int retryCounter = 0;
while (retryCounter < maxRetries) {
try {
return function.get();
} catch (Exception ex) {
retryCounter++;
log.error("FAILED - Command failed on retry " + retryCounter + " of " + maxRetries, ex);
if (retryCounter >= maxRetries) {
log.error("Max retries exceeded.");
break;
}
}
}
throw new RuntimeException("Command failed on all of " + maxRetries + " retries");
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它:
new RetryCommand<>(5).run(() -> client.getThatThing(id));
Run Code Online (Sandbox Code Playgroud)