zoukankan      html  css  js  c++  java
  • 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";
    }

  • 相关阅读:
    jmeter 5压测https接口报错javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake的解决方法
    压测部署在k8s的服务时,出现{"message":"An unexpected error occurred"}错误的可能原因
    用jmeter测试post接口body带中文参数报错,同样的body粘贴到postman里正常-----解决方法
    hive删除分区表以及修复分区表
    查看Hive表信息及占用空间
    jmeter测试的get接口中有特殊字符时的处理
    面试题-给你一个扫码支付的二维码,如何写测试用例?
    零碎的 软件测试面试题
    linux常见问题
    自动化面试常问问题
  • 原文地址:https://www.cnblogs.com/tom-plus/p/7844228.html
Copyright © 2011-2022 走看看