java 中的重试机制与 ScheduledExecutorService
A retry mechanism in java with ScheduledExecutorService
我正在尝试在java中编写一个重试机制,在失败的情况下在 3 分钟后重新绑定一个函数,并且最多重试 3 次。
我不想使用 Thread.Sleep,而是考虑使用 ScheduledExecutorService。我试图弄清楚什么是一个好的实现。看来 executor.schedule() 没有 runnable 里面的 runnable。
我在想这样的事情:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
final int count = 1;
final int MAX_RETRY = 3;
Runnable runnable = () -> {
try {
//This function can fail and throw FunctionException
callMyFunction();
}
catch (FunctionException e) {
if (++count <= MAX_RETRY) {
executor.schedule(runnable, 30*60*1000);
}
}
};
executor.execute(runnable);
我建议您使用 spring-retry 库而不是编写自己的实现。
创建一个 RetryTemplate 实例。示例代码在这里 - https://github.com/innovationchef/batchpay/blob/master/src/main/java/com/innovationchef/service/PayApiRetryTemplate.java
然后这样调用你的方法-
retryTemplate.execute(arg -> callMyFunction());
此代码似乎有效,并解决了我遇到的问题。
我无法使用 lambda 来实现我的 Runnable 函数,因为在 lambda 中没有办法让“this”引用由此行中的 lambda 表达式创建的实例:
scheduler.schedule(this, 1, TimeUnit.SECONDS);
知道如何解决这个问题吗?
完整代码如下:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
AtomicInteger counter = new AtomicInteger(1);
final int MAX_RETRY = 3;
scheduler.execute(new Runnable() {
@Override
public void run () {
try {
System.out.println("Attempt number: " + counter.get());
functionCall();
scheduler.shutdown();
}
catch (Exception e) {
if (counter.get() < MAX_RETRY) {
System.out.println("Attempt number: " + counter.getAndIncrement() + " failed.");
scheduler.schedule(this, 1, TimeUnit.SECONDS);
}
else {
System.out.println("Error message: " + e.getMessage());
scheduler.shutdown();
}
}
}
});
}
public static void functionCall() {
throw new RuntimeException("Does not work");
}
感谢@Turing85 的帮助和有用的评论。
我正在尝试在java中编写一个重试机制,在失败的情况下在 3 分钟后重新绑定一个函数,并且最多重试 3 次。 我不想使用 Thread.Sleep,而是考虑使用 ScheduledExecutorService。我试图弄清楚什么是一个好的实现。看来 executor.schedule() 没有 runnable 里面的 runnable。
我在想这样的事情:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
final int count = 1;
final int MAX_RETRY = 3;
Runnable runnable = () -> {
try {
//This function can fail and throw FunctionException
callMyFunction();
}
catch (FunctionException e) {
if (++count <= MAX_RETRY) {
executor.schedule(runnable, 30*60*1000);
}
}
};
executor.execute(runnable);
我建议您使用 spring-retry 库而不是编写自己的实现。
创建一个 RetryTemplate 实例。示例代码在这里 - https://github.com/innovationchef/batchpay/blob/master/src/main/java/com/innovationchef/service/PayApiRetryTemplate.java
然后这样调用你的方法-
retryTemplate.execute(arg -> callMyFunction());
此代码似乎有效,并解决了我遇到的问题。 我无法使用 lambda 来实现我的 Runnable 函数,因为在 lambda 中没有办法让“this”引用由此行中的 lambda 表达式创建的实例:
scheduler.schedule(this, 1, TimeUnit.SECONDS);
知道如何解决这个问题吗?
完整代码如下:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
AtomicInteger counter = new AtomicInteger(1);
final int MAX_RETRY = 3;
scheduler.execute(new Runnable() {
@Override
public void run () {
try {
System.out.println("Attempt number: " + counter.get());
functionCall();
scheduler.shutdown();
}
catch (Exception e) {
if (counter.get() < MAX_RETRY) {
System.out.println("Attempt number: " + counter.getAndIncrement() + " failed.");
scheduler.schedule(this, 1, TimeUnit.SECONDS);
}
else {
System.out.println("Error message: " + e.getMessage());
scheduler.shutdown();
}
}
}
});
}
public static void functionCall() {
throw new RuntimeException("Does not work");
}
感谢@Turing85 的帮助和有用的评论。