天天看點

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抛出的異常,否則無法識别,可以在該方法中進行日志處理。

繼續閱讀