一、重试机制的几种实现
- guava retry
- spring retry
- for/while循环+sleep
对重试有几个地方,需要仔细区分:
- 是否持久化
- 是否指数级重试
- 重试次数
- 重试间隔时间
二、power-job的重试实现
为了不依赖于guava和spring retry等框架,它采用了第三种方式--循环+sleep。
使用示例
默认重试3次,每次重试间隔100毫秒
try {
CommonUtils.executeWithRetry0(() -> omsLockRepository.deleteByLockName(name));
}catch (Exception e) {
log.error("[DatabaseLockService] unlock {} failed.", name, e);
}
String resultDTOStr = CommonUtils.executeWithRetry0(() -> HttpUtils.get(realUrl));
executeWithRetry0()
/**
* 重试执行,仅适用于失败抛出异常的方法
* @param executor 需要执行的方法
* @param tryTimes 尝试次数(总执行次数)
* @param intervalMS 失败后下一次执行的间隔时间
* @param <T> 执行函数返回值类型
* @return 函数成功执行后的返回值
* @throws Exception 执行失败,调用方自行处理
*/
public static <T> T executeWithRetry(SupplierPlus<T> executor, int tryTimes, long intervalMS) throws Exception {
if (tryTimes <= 1 || intervalMS <= 0) {
return executor.get();
}
for (int i = 1; i < tryTimes; i++) {
try {
return executor.get();
}catch (Exception e) {
Thread.sleep(intervalMS);
}
}
return executor.get();
}
public static <T> T executeWithRetry0(SupplierPlus<T> executor) throws Exception {
return executeWithRetry(executor, 3, 100);
}
SupplierPlus
函数式接口FunctionalInterface的妙用
package tech.powerjob.common.utils;
/**
* Represents a supplier of results.
*
* <p>There is no requirement that a new or distinct result be returned each
* time the supplier is invoked.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #get()}.
*
* @param <T> the type of results supplied by this supplier
*
* @author tjq
* @since 2020/3/26
*/
@FunctionalInterface
public interface SupplierPlus<T> {
/**
* Gets a result.
* @return a result
* @throws Exception allow to throw Exception
*/
T get() throws Exception;
}
网友评论