Spring Retry:優雅地實現方法重試機制

前言

在實際的軟件開發中,尤其是在涉及網絡請求、數據庫操作或外部服務調用的場景下,我們常常會遇到一些臨時性故障(Transient Failures),例如網絡波動、數據庫連接超時、第三方 API 暫時不可用等。面對這些問題,一種常見的解決方案就是自動重試機制

Spring Retry 是 Spring 提供的一個模塊,它可以幫助我們以聲明式的方式為方法添加重試功能,從而提升系統的健壯性和可用性。


一、什么是 Spring Retry?

Spring Retry 是 Spring 框架中的一個子項目,提供了對方法調用失敗后進行自動重試的支持。它不僅支持簡單的重試邏輯,還支持重試策略回退策略以及與 Spring AOP 集成,使得我們可以非常方便地在業務代碼中加入重試邏輯。


二、Spring Retry 的核心組件

1. RetryTemplate

RetryTemplate 是 Spring Retry 的核心類之一,它封裝了重試邏輯的執行過程。你可以通過配置 RetryPolicyBackOffPolicy 來定義重試次數和等待策略。

RetryTemplate retryTemplate = new RetryTemplate();// 設置最多重試3次(包括第一次嘗試)
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(3));// 設置固定間隔2秒再重試
retryTemplate.setBackOffPolicy(new FixedBackOffPolicy(2000L));retryTemplate.execute(context -> {// 調用可能會失敗的方法someService.doSomething();return null;
});

2. RetryPolicy

定義哪些異常需要重試,以及最大重試次數。常用的有:

  • SimpleRetryPolicy:基于次數的重試。
  • ExceptionClassifierRetryPolicy:根據異常類型決定是否重試。
  • NeverRetryPolicy:從不重試。
  • AlwaysRetryPolicy:無限重試。

3. BackOffPolicy

定義重試之間的等待策略。常用的有:

  • FixedBackOffPolicy:固定時間間隔。
  • ExponentialBackOffPolicy:指數退避策略(推薦)。
  • NoBackOffPolicy:不等待。

4. RetryListener

可以監聽重試的不同階段,比如開始、重試、結束等事件,用于日志記錄或監控。


三、使用注解方式實現重試(推薦)

Spring Retry 支持通過注解的方式簡化重試邏輯的編寫,只需在方法上添加 @Retryable 注解即可。

1. 引入依賴(Maven)

<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId><version>1.3.5</version>
</dependency><!-- 同時需要啟用 AspectJ -->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version>
</dependency>

2. 啟用 Retry 功能

在配置類或啟動類上加上 @EnableRetry 注解:

@SpringBootApplication
@EnableRetry
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

3. 在方法上使用 @Retryable

@Service
public class MyService {@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 2000))public void doSomething() {// 可能拋出異常的方法體if (Math.random() < 0.7) {throw new RuntimeException("Temporary failure");}System.out.println("Success!");}
}

上面的例子表示:

  • 最多嘗試 3 次;
  • 每次失敗后等待 2 秒;
  • 默認只對 RuntimeException 進行重試。

你也可以指定特定異常:

@Retryable(value = {IOException.class}, maxAttempts = 5)

或者排除某些異常:

@Retryable(exclude = {SQLException.class})

四、@Retryable 注解參數詳解

在使用 Spring Retry 的注解方式時,@Retryable 是最核心的注解之一。它提供了多個可配置項,用于定義方法的重試行為。下面是一個詳細的參數說明表:

參數名類型默認值描述
value / includeClass<? extends Throwable>[]{RuntimeException.class}指定需要重試的異常類型,默認對所有 RuntimeException 進行重試。
excludeClass<? extends Throwable>[]{}排除某些異常類型,這些異常不會觸發重試。
maxAttemptsint3最大嘗試次數(包括第一次調用)。
maxAttemptsExpressionStringnull支持通過 SpEL 表達式動態設置最大嘗試次數。
backoffBackoff@Backoff(delay = 1000L)設置退避策略,如固定延遲、指數退避等。
interceptorBeanNameString""自定義攔截器 Bean 名稱(不常用)。
labelString""給重試操作添加標簽,可用于監聽器識別。
statefulbooleanfalse是否為有狀態重試(適用于冪等性要求高的場景)。

示例:更復雜的 @Retryable 配置

@Retryable(value = {IOException.class, TimeoutException.class},exclude = SQLException.class,maxAttempts = 5,backoff = @Backoff(delay = 2000, multiplier = 1.5, maxDelay = 10000),stateful = true
)
public void retryableMethod() {// 方法邏輯
}

在這個例子中:

  • 只對 IOExceptionTimeoutException 進行重試;
  • 排除 SQLException
  • 最多重試 5 次;
  • 使用指數退避策略,初始延遲 2 秒,每次乘以 1.5 倍,最長延遲不超過 10 秒;
  • 啟用了有狀態重試(適合涉及外部狀態變更的操作);

五、高級用法:結合監聽器

你可以通過自定義監聽器來記錄每次重試的日志信息:

@Component
public class MyRetryListener implements RetryListener {@Overridepublic <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {System.out.println("Retry: Open");return true;}@Overridepublic <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {System.out.println("Retry: Close");}@Overridepublic <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {System.out.println("Retry: Error occurred, attempt " + context.getRetryCount());}
}

然后注冊到 RetryTemplate 中:

retryTemplate.registerListener(new MyRetryListener());

六、注意事項

  1. 冪等性問題:重試操作必須是冪等的,否則重復執行可能導致數據錯誤。
  2. 事務控制:如果方法處于事務中,注意事務傳播行為,避免因重試引發事務沖突。
  3. 性能影響:合理設置重試次數和等待時間,防止系統負載過高。
  4. 異步 vs 同步:Spring Retry 是同步的,如需異步重試需自行結合線程池處理。

七、總結

Spring Retry 是一個輕量但功能強大的重試框架,它通過模板模式和注解方式幫助開發者快速實現方法級別的自動重試。無論是在微服務調用、消息消費、數據庫訪問等場景中,都可以靈活應用。

合理使用 Spring Retry,可以讓我們的系統更加健壯,有效應對各種瞬時故障。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84082.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84082.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84082.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Mysql報錯

1.權限問題 MySQL 認證協議不兼容問題解決方案 這個錯誤表明您的 MySQL 客戶端與服務器要求的認證協議不兼容&#xff0c;通常發生在 MySQL 8.0 服務器與舊版客戶端之間。 nested exception is org.apache.ibatis.exceptions.PersistenceException: Error querying database. …

小米汽車5月交付量超過28000臺,與上月持平

6月1日&#xff0c;小米汽車公布5月交付數據&#xff0c;2025年5月&#xff0c;小米汽車交付量超過28000臺&#xff0c;4月官方披露的交付數據也為28000臺。 此外&#xff0c;小米汽車5月新增29家門店&#xff0c;全國82城已有298家門店&#xff1b;6月計劃新增37家門店&#x…

嚴格一致性模型

SC 的第二點約束 :store 必須被 所有(包括自身)執行流 同時看到 ,但是不要求寫操作“立即”對其他處理器可見&#xff1b;允許寫操作延遲一會兒被其他核觀察到。 而 嚴格一致性模型,包括1. store 必須被 所有(包括自身)執行流 同時看到2. 看到的時間 必須是 某個處理器完成寫操…

結合 STM32CubeMX 使用 FreeRTOS 實時操作系統

前言 在STM32CubeMX軟件出現以后&#xff0c;創建嵌入式項目變得簡潔了許多&#xff0c;開發者無需重復編寫MCU的外設初始化配置&#xff0c;只需在STM32CubeMX軟件中動動鼠標配置完畢&#xff0c;就可以自動生成基于HAL/LL庫的Keil項目文件&#xff0c;提高了開發效率。 最近想…

一致性框架:供應鏈分布式事務問題解決方案

來源&#xff1a;得物技術 一、前言 二、一致性理論基礎 1. 一致性模型概述 2. 最終一致性的必要性 三、供應鏈一致性框架總體架構 1. 一致性框架的核心功能 2. 一致性框架整體框架 3. 一致性框架整體流程 四、一致性框架實現原理 1. 核心組件設計 2. 異步執行實現原…

民國大模型:智能重構下的亂世覺醒與文明轉型

引言&#xff1a;當外灘鐘聲遇見生成式AI 在歷史博物館的數字化展廳中&#xff0c;一幅動態的《民國百景圖》正通過全息投影技術演繹十里洋場的繁華與滄桑。這個虛實交融的場景&#xff0c;恰似民國大模型技術的隱喻——以人工智能為紐帶&#xff0c;連接起北洋軍閥混戰與民族…

ROS2 筆記匯總(2) 通信接口

在 ROS 系統中&#xff0c;通信接口&#xff08;Interface&#xff09; 是節點之間傳遞信息的標準“語言協議”&#xff0c;確保了不同功能節點之間可以正確理解和使用彼此傳送的數據內容。我們可以將其理解為“數據結構格式定義”&#xff0c;貫穿于話題&#xff08;Topic&…

微信小程序:將搜索框和表格封裝成組件,頁面調用組件

一、實現效果 實現搜索框,表格和翻頁效果 二、組件實現 1、創建表格組件頁面 (1)創建文件 在文件根目錄(與pages同級)直接創建components文件夾,并創建表格的頁面common-table/index (2)視圖層 a、寫入表頭 循環由主頁面傳遞的columns,數據為字段名label,寬度為設置…

基于貝葉斯學習方法的塊稀疏信號壓縮感知算法

基于貝葉斯學習方法的塊稀疏信號壓縮感知算法 BSBL-FM-master/BSBL_BO.m , 15593 BSBL-FM-master/BSBL_FM.m , 12854 BSBL-FM-master/Phi.mat , 131256 BSBL-FM-master/README.md , 3954 BSBL-FM-master/demo.mat , 1610 BSBL-FM-master/demo_fecg.m , 1481 BSBL-FM-master/de…

【Python爬蟲】requests知識點講解

目錄 前言1. requests庫基礎1.1 安裝requests1.2 基本導入 2. HTTP請求方法2.1 GET請求2.2 POST請求2.3 其他HTTP方法 3. 請求頭設置3.1 User-Agent設置3.2 常用請求頭 4. 響應處理4.1 響應內容獲取4.2 響應狀態碼4.3 響應頭信息 5. 會話管理5.1 Session對象5.2 Cookie處理 6. …

服務器上安裝配置vsftpd

目錄 1. 安裝vsftpd服務 2、修改配置文件 3. 修改用戶白名單 4. 通過ftp客戶端命令登錄ftp服務器 5. 參考資料 1. 安裝vsftpd服務 執行命令安裝vsftp服務、和ftp客戶端 yum install vsftpd yum install ftp 2、修改配置文件 在服務器上先創建一個系統用戶&#xff0c;待…

C#實現圖片文字識別

這幾年的AI的發展&#xff0c;使得文字識別難度大大降低、精度大大的提高。百度飛漿就是一個非常好的AI框架&#xff0c;而且是開源的。 我們利用百度飛漿就能快速簡單的實現文字識別功能&#xff0c;幾行代碼就可以集成。 其中百度飛漿的PaddleOCR&#xff0c;就是專門針對文…

Android Framework 調用棧

在Android Framework開發中&#xff0c;添加調用棧&#xff08;Call Stack&#xff09;是調試復雜問題&#xff08;如崩潰、死鎖或流程追蹤&#xff09;的核心手段。 一、Java層調用棧添加 適用于Activity、Service等組件或Framework中的Java代碼。 基礎方法&#xff1a; 使用…

Ollama安裝非系統盤操作方法(2025年6月測試通過)

Ollama是當前部署大模型比較便利的工具&#xff0c;但是默認會將軟件和模型都安裝到C盤下&#xff0c;導致系統盤爆表&#xff0c;建議將軟件和模型都放置在非系統盤。 1. 軟件安裝在非系統盤 &#xff08;1&#xff09;在D盤下手動創建ollama目錄 &#xff08;2&#xff09…

《HTTP權威指南》 第1-2章 HTTP和URL基礎

HTTP請求基礎 格式化數據塊稱為HTTP報文 請求報文&#xff1a;從客戶端發往服務器的HTTP報文&#xff0c;只有請求起始行請求首部&#xff0c;沒有請求主體 響應報文&#xff1a;從服務器發往客戶端的報文&#xff0c;包含響應起始行響應首部響應主體 HTTP報文通過傳輸控制…

9. TypeScript 泛型

TypeScript 中的泛型使開發者能夠編寫靈活、可重用的代碼&#xff0c;同時保持類型安全。它們允許動態定義類型&#xff0c;確保函數、類和接口可以適用于任何數據類型。這有助于避免重復&#xff0c;提高代碼的模塊化&#xff0c;使其既類型安全又具備適應性。 一、認識泛型 …

Apache Iceberg與Hive集成:分區表篇

一、Iceberg分區表核心概念與Hive集成原理 1.1 分區表在大數據場景的價值 在大規模數據分析中&#xff0c;分區表通過將數據按特定維度&#xff08;如時間、地域、業務類型&#xff09;劃分存儲&#xff0c;可顯著提升查詢效率。Apache Iceberg的分區表設計融合了Hive的分區理…

SAST + IAST + DAST 全鏈路防護體系構建方案

&#x1f525;「炎碼工坊」技術彈藥已裝填&#xff01; 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 1. 生命周期分層嵌入&#xff08;防御縱深&#xff09; 階段工具防護重點集成觸發點編碼階段SAST源碼漏洞&#xff08;硬編碼密鑰、SQL注入模式&#x…

pnpm link如何不踩坑

前提一&#xff1a;我有一個source-project源碼庫&#xff0c;有一個develop-project項目庫。想使用pnpm link對source-project進行本地調試。 前提二&#xff1a;source-project源碼庫已打包 本地調試詳細步驟如下&#xff1a; 1、檢查是否配置了系統環境變量&#xff0c;P…

vue3 javascript 多字段求和技巧

在 Vue 3 中&#xff0c;如果你需要在一個組件中處理多個字段的求和&#xff0c;你可以通過計算屬性&#xff08;computed properties&#xff09;或者方法&#xff08;methods&#xff09;來實現。這里我將展示兩種主要的方法&#xff1a; 方法 1&#xff1a;使用計算屬性&am…