日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

5分钟攻略Spring-Retry框架实现经典重试场景

發布時間:2023/12/24 javascript 40 coder
生活随笔 收集整理的這篇文章主要介紹了 5分钟攻略Spring-Retry框架实现经典重试场景 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

今天分享干貨,控制了篇幅,5分鐘內就能看完學會。

主題是Spring-Retry框架的應用,做了一個很清晰的案例,代碼可下載自測。

框架介紹

Spring-Retry框架是Spring自帶的功能,具備間隔重試包含異常排除異常控制重試頻率等特點,是項目開發中很實用的一種框架。

本篇所用框架的版本如下:

技術 版本
Java 17
SpringBoot 3.2
Spring-retry 2.0.4

正文

1、引入依賴

坑點:需要引入AOP,否則會拋異常。

<!-- Spring-Retry -->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>
<!-- Spring-AOP -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、啟動類注解

坑點:很容易一時疏忽忘記啟動類開啟@EnableRetry,大家別忘了哦。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;

@SpringBootApplication
@EnableRetry
public class SpringRetryDemoApplication {

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

}

3、模擬發短信

我們模擬一個發短信功能,根據隨機數分別作為成功、失敗、拋出各種異常的入口。

這里拋出幾種異常的目的,是為了后面演示出重試注解參數產生的效果。

import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 短信服務工具類
 * </p>
 *
 * @author 程序員濟癲
 * @since 2023-12-21 09:40
 */
@Slf4j
public class SmsUtil {

   /**
    * 發送短信
    */
   public static boolean sendSms() {

      // 使用隨機數模擬重試場景
      int num = RandomUtil.randomInt(4);
      log.info("[SmsUtil][sendSms]>>>> random num = {}", num);

      return switch (num) {
         case 0 ->
               // 模擬發生參數異常
               throw new IllegalArgumentException("參數有誤!");
         case 1 ->
               // 模擬發生數組越界異常
               throw new ArrayIndexOutOfBoundsException("數組越界!");
         case 2 ->
               // 模擬成功
               true;
         case 3 ->
               // 模擬發生空指針界異常
               throw new NullPointerException();
         default ->
               // 未成功則返回false
               false;
      };

   }
}

4、Retry應用

我們單獨寫一個用于重試調用的組件類,用于業務類調用。

import com.example.springretrydemo.util.SmsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * <p>
 * 重試組件
 * </p>
 *
 * @author 程序員濟癲
 * @since 2023-12-21 09:43
 */
@Slf4j
@Component
public class RetryComponent {

   /**
    * 重試機制發送短信
    */
   @Retryable(
         retryFor = {IllegalArgumentException.class, ArrayIndexOutOfBoundsException.class},
         noRetryFor = {NullPointerException.class},
         maxAttempts = 4,
         backoff = @Backoff(delay = 2000L, multiplier = 2)
   )
   public boolean sendSmsRetry() {

      log.info("[RetryComponent][sendSmsRetry]>>>> 當前時間:{}", getNowTime());
      return SmsUtil.sendSms();
   }

   /**
    * 兜底方法,規則:
    *        1、超出了最大重試次數;
    *        2、拋出了不進行重試的異常;
    */
   @Recover
   public boolean recover() {
      log.info("[RetryComponent][recover]>>>> 短信發送次數過多,請稍后重試!");
      return false;
   }

   /**
    * 獲取當前時間
    */
   private String getNowTime() {

      return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
   }
}

@Retryable注解參數說明:

  • retryFor:此參數包含的異常會觸發重試機制,多個異常則以數組形式定義。
  • noRetryFor:此參數包含的異常不會觸發重試機制,多個異常則以數組形式定義。
  • maxAttempts:重試最大次數,不定義則默認3次。
  • backoff:定義補償機制,delay-延遲時間(s),multiplier-重試時間的倍數(比如設置為2,重試4次的話,補償機制就是分別間隔2s、4s、8s做重試)

@Recover注解說明:用于兜底,當 超出了最大重試次數拋出了不進行重試的異常 時,直接執行該注解聲明的兜底方法。

PS:順便提一句,如果是 SpringBoot2.x 的版本,這里@Retryable注解的retryFor參數對應的是includenoRetryFor參數對應的是exclude,可以直接點進去看源碼便一目了然。


5、JunitTest測試

我們編寫一個Junit測試類來測試重試的效果,并打印出結果信息。

import com.example.springretrydemo.retry.RetryComponent;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@Slf4j
@SpringBootTest
class SpringRetryDemoApplicationTests {

   @Autowired
   private RetryComponent retryComponent;

   @Test
   void sendSmsTest() {
      boolean ret = retryComponent.sendSmsRetry();
      log.info("sendSmsTest result = {}", ret);
   }

}

6、效果

第1次測試時,可以看到,隨機數剛好都是1,走的是數組越界異常。

而這個異常在retryFor中定義了,所以執行了4次,直到結束,最后進入了兜底方法。

同時,可以看到,執行4次的頻率也和預想一樣是2s、4s、8s。

第2次測試時,可以看到,隨機數是3,走的是空指針異常。

而這個異常在noRetryFor中定義了,所以接下來直接進入了兜底方法。

第3次測試時,可以看到,第一次隨機數是0,走的參數異常,在retryFor中,所以2s后繼續重試。

然后隨機數是2,表示業務成功,所以直接返回了true。

這個場景就很像大家經常遇見的補償操作,第一次發生異常失敗,第二次重試后又成功了。

總結

Spring-retry框架還是挺實用的,但不是萬能的。

優點是,簡化了重試邏輯,提供了現成的重試策略,具備一定靈活性。

缺點,也很明顯,生產環境使用有風險,比如在復雜場景下配置的策略有問題,有可能會導致無限重試,這個后果不用說大家也能想象。

所以,使用這個框架,一定要明確好場景再使用,我這里不推薦復雜場景下使用,因為君子不立于危墻之下

好了,今天的知識點你學會了嗎?

完整代碼:戳這里 --> Gitee


喜歡請點贊+關注↑↑↑,持續分享干貨哦~

總結

以上是生活随笔為你收集整理的5分钟攻略Spring-Retry框架实现经典重试场景的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。