package com.huakai.springenv.retry.v2;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
@Slf4j
public class RetryUtil {
public static ExecutorService EXECUTOR = Executors.newFixedThreadPool(1);
private static final ScheduledExecutorService SCHEDULER_EXECUTOR = Executors.newScheduledThreadPool(20);
/**
* 任务重试
* @param actualTaskFunction 执行的任务函数
* @param resultHandler 任务结果处理器
* @param maxRetry 最大重试次数
* @param retryStrategy 重试策略
*/
public static void retryTask(
Function<Integer, String> actualTaskFunction,
Function<String, Boolean> resultHandler,
int maxRetry,
RetryStrategy retryStrategy // 使用策略模式
) {
Runnable runnable = new Runnable() {
final AtomicInteger retryCount = new AtomicInteger(); // 当前重试次数
final AtomicInteger maxRetryCount = new AtomicInteger(maxRetry); // 最大重试次数
@Override
public void run() {
String taskResult = actualTaskFunction.apply(retryCount.get()); // 执行任务
Boolean taskSuccess = resultHandler.apply(taskResult); // 处理任务结果
if (taskSuccess) {
if (retryCount.get() > 1) {
log.info("任务重试成功,重试次数:{}", retryCount.get());
}
return; // 任务成功,不需要再重试
}
if (retryCount.incrementAndGet() == maxRetryCount.get()) {
log.warn("任务重试失败,重试次数:{}", retryCount.get());
return; // 达到最大重试次数,停止重试
}
// 获取重试间隔
long delay = retryStrategy.getDelay(retryCount.get());
TimeUnit timeUnit = retryStrategy.getTimeUnit(retryCount.get());
// 安排下次重试
SCHEDULER_EXECUTOR.schedule(this, delay, timeUnit);
log.info("任务重试失败,等待 {} {} 后再次尝试,当前重试次数:{}", delay, timeUnit, retryCount.get());
}
};
EXECUTOR.execute(runnable); // 执行任务
}
public static void main(String[] args) {
// 使用指数退避重试策略
RetryStrategy retryStrategy = new ExponentialBackoffRetryStrategy(1, TimeUnit.SECONDS);
retryTask(
retryCount -> "task result",
taskResult -> Math.random() < 0.1,
5,
retryStrategy
);
}
}
|