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)@Documentedpublic @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@Componentpublic 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); } }}