Java接口请求失败重试机制

本文详细介绍了Spring Retry的使用方法,包括Maven依赖配置、注解应用、Retryable和RetryTemplate的实战,以及如何自定义AOP注解进行异常重试。同时涵盖了重试失效场景和不同重试策略的配置。
摘要由CSDN通过智能技术生成

一、SpringRetry

1、引入maven依赖

        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

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<? extends Exception>[] 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;
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值