重试抽象类 RetryTemplate.class
package com.test.demo.core.service.template;
import com.test.common.logging.Logger;
import com.test.common.logging.LoggerFactory;
import com.test.demo.common.util.log.LoggerConstants;
import com.test.demo.common.util.log.LoggerUtil;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.FutureTask;
public abstract class RetryTemplate {
private static final int DEFAULT_RETRY_TIME = 1;
private int retryTime = DEFAULT_RETRY_TIME;
private static final Logger LOGGER = LoggerFactory.getLogger(RetryTemplate.class);
/**
* 重试的睡眠时间,毫秒
*/
private int sleepTime = 0;
public int getSleepTime() {
return sleepTime;
}
public RetryTemplate setSleepTime(int sleepTime) {
if(sleepTime < 0) {
throw new IllegalArgumentException("sleepTime should equal or bigger than 0");
}
this.sleepTime = sleepTime;
return this;
}
public int getRetryTime() {
return retryTime;
}
public RetryTemplate setRetryTime(int retryTime) {
if (retryTime <= 0) {
throw new IllegalArgumentException("retryTime should bigger than 0");
}
this.retryTime = retryTime;
return this;
}
/**
* 重试的业务执行代码
* 失败时请抛出一个异常
*
* 确定返回的封装类,根据返回结果的状态来判定是否需要重试,doBiz方法抛出异常时重试,直到重试次数使用完或不再抛出异常
*
* @return Object
*/
protected abstract Object doBiz() throws Exception;
public Object execute() throws InterruptedException {
for (int i = 0; i < retryTime; i++) {
try {
return doBiz();
} catch (Exception e) {
LoggerUtil.error(LoggerConstants.ERROR_LOGGER, e, "系统异常,第 " + (i + 1) + " 次重试失败");
Thread.sleep(sleepTime);
}
}
return null;
}
public FutureTask<Object> submit(ExecutorService executorService) {
if (executorService == null) {
throw new IllegalArgumentException("please choose executorService!");
}
FutureTask<Object> futureTask = new FutureTask<Object>(new Callable<Object>() {
@Override
public Object call() throws Exception {
LoggerUtil.info(LOGGER, "Asynchronous Callable");
// 开始执行业务逻辑
for (int i = 0; i < retryTime; i++) {
try {
return doBiz();
} catch (Exception e) {
LoggerUtil.error(LoggerConstants.ERROR_LOGGER, e, "系统异常,第 " + (i + 1) + " 次重试失败");
Thread.sleep(sleepTime);
}
}
return null;
}
});
return futureTask;
}
}
用例演示伪代码:
final ExecutorService exec = Executors.newFixedThreadPool(1);
FutureTask<Object> futureTask = new RetryTemplate() {
@Override
protected Result doBiz() throws Exception {
// 执行业务逻辑,上抛异常触发重试
Result result = do();
if (condition) {
throw new Exception("获取result为空");
}
return result;
}
// 重试次数 2000 次, 每次重试间隔 5 毫秒
}.setRetryTime(2000).setSleepTime(5).submit(exec);
// 执行线程
exec.submit(futureTask);
Result result = new Result();
try {
// 限时 1 s,超过1s,终止重试
result = (Result) futureTask.get(1000 * 1, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
// 关闭线程池
exec.shutdown();
LoggerUtil.error(LoggerConstants.BIZ_SERVICE_IMPL, "[ time limit task] timeout", e);
} catch (Exception e) {
LoggerUtil.error(LoggerConstants.BIZ_SERVICE_IMPL, "[ time limit task] end-failed", e);
} finally {
// 关闭线程池
if (exec != null) {
exec.shutdown();
}
}
// result即为最终执行结果
return result;











网友评论