spring boot下接口調用失敗重試方案


背景:

在項目開發中,有時候會出現接口調用失敗,本身調用又是異步的,如果是因為一些網絡問題請求超時,總想可以重試幾次把任務處理掉。

一些RPC框架,比如dubbo都是有重試機制的,但是並不是每一個項目多會使用dubbo框架,常規的小項目有時候直接使用http進行不同項目之間的交互。

 

個人想法:

使用spring aop和自定義注解來,建立一套重試機制。

根據切入點和自定義注解,來完成重試工作。

 

exps:

定義一個注解:

 1 import org.springframework.stereotype.Component;
 2 
 3 import java.lang.annotation.Documented;
 4         import java.lang.annotation.ElementType;
 5         import java.lang.annotation.Retention;
 6         import java.lang.annotation.RetentionPolicy;
 7         import java.lang.annotation.Target;
 8 
 9 @Retention(RetentionPolicy.RUNTIME)
10 @Target(ElementType.METHOD)
11 @Documented
12 @Component
13 public @interface RetryProcess {
14  //重試的次數
15  int value() default 1;
16 }
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

@Aspect
@Component
public class AspectExceptionInterceptor {
    private  final Logger logger = LoggerFactory.getLogger(this.getClass());
    @AfterThrowing(pointcut=("execution(* com.tom.plus.ctl..*(..)) && @annotation(com.tom.plus.compent.RetryProcess)"))
    public void tryAgain(JoinPoint point) {
        logger.info("------------開始重試------------");
        try {
            Object object = point.getTarget();
            Field field = object.getClass().getDeclaredField("threadLocal");
            field.setAccessible(true);
            ThreadLocal<AtomicInteger> threadLocal = (ThreadLocal<AtomicInteger>) field.get(object);
            MethodSignature methodSignature = (MethodSignature) point.getSignature();
            RetryProcess retryProcess = methodSignature.getMethod().getAnnotation(RetryProcess.class);
            if (threadLocal.get().intValue() < retryProcess.value()) {
               int index = threadLocal.get().incrementAndGet();
                logger.info("開始重試第"+index);
                MethodInvocationProceedingJoinPoint methodPoint = ((MethodInvocationProceedingJoinPoint) point);
                methodPoint.proceed();
            }
        } catch (Throwable throwable) {
            //logger.error("重試失敗",throwable);
            tryAgain(point);
        }
    }
}

測試代碼:

@RetryProcess(value = 2)
@RequestMapping("/hero")
@ResponseBody
public String doIt2() {
//該接口會拋出異常,啟動進行重試機制
testService.doProcess();
return "success";
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM