• 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";
    }

  • 相关阅读:
    python之read()方法
    python之高阶函数
    python之lambda表达式的应用
    DevExpress.XtraGrid.view.gridview 说明文
    C# SQL时间格式
    GridControl自动定位至符合条件的行
    用sql命令修改数据表
    用C#编程从数据库中读取图片数据导进Excel文件的方法(如何从数据库中读取保存的文件,直接打开,中间不保存到本地)
    DevExpress中GridControl的属性设置及动态绑定数据和全选取消全选
    C# 导出数据到Excel模板中
  • 原文地址:https://www.cnblogs.com/tom-plus/p/7844228.html
Copyright © 2020-2023  润新知