关于java:重试机制

45次阅读

共计 1777 个字符,预计需要花费 5 分钟才能阅读完成。

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);
        }
    }

}

正文完
 0