1、try-catch-redo 简略重试模式
try {result = uploadToOdps(paramMap);
if (!result) {Thread.sleep(1000);
uploadToOdps(paramMap); // 一次重试
}
} catch (Exception e) {Thread.sleep(1000);
uploadToOdps(paramMap);// 一次重试
实现简略,然而代码冗余
2、Spring Retry
https://www.cnblogs.com/jtlgb/p/6813164.html
应用 Spring 框架去实现,无侵入式,贴正文即可
3、应用 For 循环来实现
for (int i = 0; i < 3; i++) {
try {
xxx;
break;
} catch (Exception e) {
xxx;
Thread.sleep(1000);
continue;
}
}
4、应用 AOP 切面去实现
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Retryable {
/**
* Exception type that are retryable.
* @return exception type to retry
*/
Class<? extends Throwable> value() default RuntimeException.class;
/**
* 蕴含第一次失败
* @return the maximum number of attempts (including the first failure), defaults to 3
*/
int maxAttempts() default 3;}
@Aspect
@Component
public class RetryAspect {@Pointcut("execution(public * com.github.houbb.retry.aop..*.*(..)) &&" +
"@annotation(com.github.houbb.retry.aop.annotation.Retryable)")
public void myPointcut() {}
@Around("myPointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {Method method = getCurrentMethod(point);
Retryable retryable = method.getAnnotation(Retryable.class);
//1. 最大次数判断
int maxAttempts = retryable.maxAttempts();
if (maxAttempts <= 1) {return point.proceed();
}
//2. 异样解决
int times = 0;
final Class<? extends Throwable> exceptionClass = retryable.value();
while (times < maxAttempts) {
try {return point.proceed();
} catch (Throwable e) {
times++;
// 超过最大重试次数 or 不属于以后解决异样
if (times >= maxAttempts ||
!e.getClass().isAssignableFrom(exceptionClass)) {throw new Throwable(e);
}
}
}
return null;
}
private Method getCurrentMethod(ProceedingJoinPoint point) {
try {Signature sig = point.getSignature();
MethodSignature msig = (MethodSignature) sig;
Object target = point.getTarget();
return target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
} catch (NoSuchMethodException e) {throw new RuntimeException(e);
}
}
}