Java接口请求失败重试机制

一、SpringRetry

1、引入maven依赖

        
            org.springframework.retry
            spring-retry
        
        
            org.aspectj
            aspectjweaver
        

2、启动类,或配置类加注解@EnableRetry

3、在需要重试的方法上加注解

@Retryable(value = Exception.class, maxAttempts = 3,
          backoff = @Backoff(delay = 5000L,multiplier = 2))

Retryable注解的方法在发生异常时会重试,参数说明:
value:当指定异常发生时会进行重试 ,HttpClientErrorException是RestClientException的子类。
include:和value一样,默认空。如果 exclude也为空时,所有异常都重试
exclude:指定异常不重试,默认空。如果 include也为空时,所有异常都重试
maxAttemps:最大重试次数,默认3
backoff:重试等待策略,默认空
@Backoff注解为重试等待的策略,参数说明:
delay:指定重试的延时时间,默认为1000毫秒
multiplier:指定延迟的倍数,比如设置delay=5000,multiplier=2时,第一次重试为5秒后,第二次为10(5x2)秒,第三次为20(10x2)秒。
 

4.重试失效场景

  1. 本类内部调用的方法不能使用
    public class demo {
        public void A() {
            B();
        }
    
        @Retryable(Exception.class)
        public void B() {
            throw new RuntimeException("retry...");
        }
    }
  2. 使用@Retryable不能使用try catch捕获异常

二、RetryTemplate

在不适用SpringRetry的情况下使用

private RetryTemplate withRetry() {
        RetryTemplate retryTemplate = new RetryTemplate();
        //重试次数
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3, Collections.singletonMap(Exception.class, true));
        retryTemplate.setRetryPolicy(retryPolicy);
        //固定时间重试机制
        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(5000);
        retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
        return retryTemplate;
    }


try {
    withRetry().execute(context -> {
        //...
        return null;
    });
} catch (RuntimeException re) {
    // ..
}

或配置类创建RetryTemplate

@Configuration
public class RetryTemplateConfiguration {

    @Bean
    public RetryTemplate retryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();
        //重试次数
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(3);
        retryTemplate.setRetryPolicy(retryPolicy);
        //固定时间重试机制
        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(5000);
        retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
        return retryTemplate;
    }
}
retryTemplate.execute(context -> {
    return this.push(array, finalReceiveAddr);
});

三、自己实现aop注解

1、注解定义

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Retry {

	int num() default 3;

	Class[] value() default {Exception.class};

}

2、切面方法

@Slf4j
@Aspect
@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class RetryAspect {

	@Pointcut("@annotation(com.test.common.aop.Retry)")
	public void retryAspect() {
	}

	@Around("retryAspect()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
		Retry retry = method.getDeclaredAnnotation(Retry.class);
		try {
			return joinPoint.proceed(joinPoint.getArgs());
		} catch (Exception e) {
			Exception exception = e;
			for (int i = 0; i < retry.num(); i++) {
				log.warn("执行失败,进入第{}次重试", i + 1);
				for (Class cls : retry.value()) {
					if (!cls.isInstance(exception)) {
						continue;
					}
					try {
						return joinPoint.proceed(joinPoint.getArgs());
					} catch (Exception e1) {
						exception = e1;
					}
				}
			}
			throw e;
		}
	}

}

你可能感兴趣的:(其他,java,spring,开发语言)