天天看点

spring boot使用@Retryable来进行重处理

  1. 应用场景

    发送消息失败

    ,调用远程服务失败,争抢锁失败等

    发消息后其他系统要处理,不知道接到消息会是什么时间。接到的消息需要监听rabbit MQ的队列取出数据。然后把所有消息都放到redis中,需要哪个消息就去取,取回来后再在redis中把取到的消息删掉。

  2. pom引用
<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.3.0</version>
</dependency>
           
  1. 启动类或者配置类上加@EnableRetry注解,启用这个功能

    与定时任务类似,重试的默认开关是关闭的,需要开启下这个功能@EnableRetry:开启重试功能

@EnableScheduling
@EnableRetry
@SpringBootApplication
public class HelloApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class, args);
    }

}
           
  1. 在指定方法上标记@Retryable来开启重试

    value:当出现这种异常时,进行重试

    maxAttempts:尝试次数 默认是3次

    backoff:重试补偿机制,默认没有。可以指定暂停时间

    multiplier :(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。

    exclude:指定不处理的异常

    include:和value一样,默认为空,当exclude也为空时,默认所有异常

@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))   
 public String getSendMsgFromRedis(String redisKey,String uuid) throws Exception {
	logger.info(*****getSendMsgFromRedis start******);
	String data=(String)redisTemplate.opsForHash().get(redisKey,uuid);
	if(null==data){
		throw new Exception("未查到数据")
	}
	return data;
};
           

@Retryable注解使用需要注意的地方:

1.由于是基于AOP实现,所以不支持类里自调用方法

2.如果重试失败需要给@Recover注解的方法做后续处理,那这个重试的方法不能有返回值,只能是void

3.方法内不能使用try catch,只能往外抛异常

4. @Recover注解来开启重试失败后调用的方法(注意,需跟重处理方法在同一个类中),此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。

继续阅读