spring|spring boot下接口调用失败重试方案

背景: 在项目开发中,有时候会出现接口调用失败,本身调用又是异步的,如果是因为一些网络问题请求超时,总想可以重试几次把任务处理掉。
一些RPC框架,比如dubbo都是有重试机制的,但是并不是每一个项目多会使用dubbo框架,常规的小项目有时候直接使用http进行不同项目之间的交互。

个人想法: 使用spring aop和自定义注解来,建立一套重试机制。
根据切入点和自定义注解,来完成重试工作。
【spring|spring boot下接口调用失败重试方案】
exps:
定义一个注解:

1 import org.springframework.stereotype.Component; 2 3 import java.lang.annotation.Documented; 4import java.lang.annotation.ElementType; 5import java.lang.annotation.Retention; 6import java.lang.annotation.RetentionPolicy; 7import java.lang.annotation.Target; 8 9 @Retention(RetentionPolicy.RUNTIME) 10 @Target(ElementType.METHOD) 11 @Documented 12 @Component 13 public @interface RetryProcess { 14//重试的次数 15int 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 { privatefinal 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 threadLocal = (ThreadLocal) 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 = https://www.it610.com/article/2)
@RequestMapping("/hero")
@ResponseBody
public String doIt2() {
//该接口会抛出异常,启动进行重试机制
testService.doProcess();
return "success";
}

转载于:https://www.cnblogs.com/tom-plus/p/7844228.html

    推荐阅读