重學SpringBoot3-Spring Retry實踐

更多SpringBoot3內容請關注我的專欄:《SpringBoot3》
期待您的點贊??收藏評論

重學SpringBoot3-Spring Retry實踐
  • 1. 簡介
  • 2. 環境準備
  • 3. 使用方式
    • 3.1 注解方式
      • 基礎使用
      • 自定義重試策略
      • 失敗恢復機制
      • 重試和失敗恢復效果
      • 注意事項
    • 3.2 編程式使用
    • 3.3 監聽重試過程
      • 監聽重試效果
  • 4. 最佳實踐
  • 5. 總結

1. 簡介

Spring Retry是Spring生態系統中的一個重要組件,它提供了自動重試失敗操作的能力。在分布式系統中,由于網絡抖動、服務暫時不可用等臨時性故障,重試機制顯得尤為重要。本文將詳細介紹如何在 SpringBoot 3 應用中集成和使用 Spring Retry。

2. 環境準備

首先在 SpringBoot 3 項目中添加必要的依賴:

<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId><version>2.0.5</version>
</dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>6.1.13</version>
</dependency>

在啟動類或配置類上添加 @EnableRetry 注解以啟用重試功能:

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

3. 使用方式

3.1 注解方式

基礎使用

最簡單的使用方式是通過 @Retryable 注解:

@Service
public class UserService {@Retryablepublic void riskyOperation() {// 可能失敗的操作}
}
自定義重試策略

可以通過 @Retryable 注解的參數來自定義重試行為:

@Service
@Slf4j
public class EmailServiceImpl implements IEmailService {@Resourceprivate JavaMailSender mailSender;@Value("${spring.mail.username}")private String from;/*** 發送簡單文本郵件** @param to* @param subject* @param text*/@Override@Retryable(retryFor = MailSendException.class, maxAttempts = 3, backoff = @Backoff(delay = 1000))public void sendSimpleEmail(String to, String subject, String text) {try {SimpleMailMessage message = new SimpleMailMessage();message.setFrom(from);message.setTo(to);message.setSubject(subject);message.setText(text);mailSender.send(message);log.info("Simple email sent successfully to: {}", to);} catch (Exception e) {log.error("Failed to send simple email", e);throw new MailSendException("Failed to send email", e);}}
}

當執行發生指定異常,將會嘗試進行重試,一旦達到最大嘗試次數,但仍有異常發生,就會拋出 ExhaustedRetryException。重試最多可進行三次,兩次重試之間的延遲時間默認為一秒。

失敗恢復機制

使用 @Recover 注解定義重試失敗后的恢復方法:

    /*** 發送簡單文本郵件** @param to* @param subject* @param text*/@Override@Retryable(retryFor = MailSendException.class, // 指定異常類型maxAttempts = 3, // 最大重試次數backoff = @Backoff(delay = 1000) // 指定退避策略,例如延遲時間)public void sendSimpleEmail(String to, String subject, String text) {try {SimpleMailMessage message = new SimpleMailMessage();message.setFrom(from);message.setTo(to);message.setSubject(subject);message.setText(text);mailSender.send(message);log.info("Simple email sent successfully to: {}", to);} catch (Exception e) {log.error("Failed to send simple email", e.getMessage());throw new MailSendException("Failed to send email", e);}}@Recoverpublic void recover(MailSendException e, String param) {// 處理最終失敗的情況log.error("Final recovery : {}", param);}
重試和失敗恢復效果

重試和失敗恢復效果

注意事項

注意@Recover 失效的情況:

  • @Recover 方法的參數類型與實際異常不匹配;
  • @Recover 方法的返回類型與 @Retryable 方法不一致;
  • @Recover 方法的其他參數與 @Retryable 方法參數不匹配。

3.2 編程式使用

除了注解方式,Spring Retry 還提供了 RetryTemplate 用于編程式重試:

@Configuration
public class RetryConfig {@Beanpublic RetryTemplate retryTemplate() {RetryTemplate template = new RetryTemplate();// 配置重試策略SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();retryPolicy.setMaxAttempts(3);// 配置退避策略FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();backOffPolicy.setBackOffPeriod(1000L);template.setRetryPolicy(retryPolicy);template.setBackOffPolicy(backOffPolicy);return template;}
}

使用RetryTemplate:

@Service
public class UserService {@Autowiredprivate RetryTemplate retryTemplate;public void executeWithRetry() {retryTemplate.execute(context -> {// 需要重試的業務邏輯return null;});}
}

3.3 監聽重試過程

通過實現RetryListener接口,可以監聽重試的整個生命周期:

public class CustomRetryListener extends RetryListenerSupport {@Overridepublic <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {// 記錄錯誤日志log.error("Retry error occurred", throwable);}@Overridepublic <T, E extends Throwable> void close(RetryContext context,RetryCallback<T, E> callback, Throwable throwable) {// 重試結束時的處理log.info("Retry completed");}
}

將監聽器注冊到RetryTemplate:

@Configuration
public class RetryConfig {@Beanpublic RetryTemplate retryTemplate() {RetryTemplate template = new RetryTemplate();// ... 其他配置 ...template.registerListener(new CustomRetryListener());return template;}
}
監聽重試效果

監聽重試過程

4. 最佳實踐

  1. 明確重試場景:只對臨時性故障使用重試機制,對于業務錯誤或永久性故障應直接失敗。

  2. 設置合理的重試次數:通常3-5次即可,過多的重試可能會加重系統負擔。

  3. 使用退避策略:建議使用指數退避策略(ExponentialBackOffPolicy),避免立即重試對系統造成沖擊。

  4. 添加監控和日志:通過RetryListener記錄重試情況,便于問題排查。

  5. 設置超時時間:避免重試過程持續時間過長。

5. 總結

Spring Retry為Spring應用提供了強大而靈活的重試機制,既可以通過注解優雅地實現重試,也可以使用RetryTemplate進行更細粒度的控制。在實際應用中,合理使用重試機制可以提高系統的健壯性和可用性。

需要注意的是,重試機制并非萬能藥,在使用時要根據具體場景選擇合適的重試策略,并做好監控和告警,以便及時發現和處理問題。

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

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

相關文章

vue3中解決組件間 css 層級問題最佳實踐(Teleport的使用)

定義&#xff1a; <Teleport> 是 Vue 3 中引入的一個內置組件&#xff0c;用于將組件的內容渲染到 DOM 中的指定位置&#xff0c;而不受組件層級結構的限制。這在處理模態框、通知、下拉菜單等需要脫離當前組件層級的情況下非常有用。 通俗來說&#xff0c;Teleport的功…

密度提升30%!Intel 18A工藝正式開放代工

快科技2月23日消息&#xff0c;Intel官方網站悄然更新了對于18A(1.8nm級)工藝節點的描述&#xff0c;稱已經做好了迎接客戶項目的準備&#xff0c;將在今年上半年開始流片&#xff0c;有需求的客戶可以隨時聯系。 Intel宣稱&#xff0c;這是在北美地區率先量產的2nm以下工藝節…

docker中常用的命令

一、服務命令 systemctl start docker.service 啟動docker服務 systemctl stop docker.service 關閉docker服務 systemctl enable docker.service 設置docker服務開機啟動 systemctl disable docker.service .禁止docker服務開機自啟動 二、鏡像命令 d…

架構師論文《智慧醫療系統中的數據集成與共享》

智慧醫療系統中的數據集成與共享 摘要 隨著醫療信息化的發展&#xff0c;如何實現跨系統、跨機構的數據集成與共享成為智慧醫療建設的核心問題。2019年&#xff0c;我所在的醫療科技公司承接了某省衛生健康委員會主導的“區域醫療信息化平臺”項目。該平臺旨在整合區域內三甲醫…

請求go構建緩存,go clean -cache

go clean -cache go 構建時會產生很多緩存&#xff0c; 一般是目錄&#xff1a;/Users/xxx/Library/Caches/go-build 此目錄README&#xff1a; This directory holds cached build artifacts from the Go build system. Run "go clean -cache" if the directory …

mybatis從接口直接跳到xml的插件

在使用 MyBatis(包括 MyBatis-Plus)時,如果你希望從接口方法直接跳轉到對應的 XML 映射文件中的 SQL 語句定義,可以借助一些開發工具或插件來實現這一功能。以下是幾種常見的方法和插件推薦: 方法一:使用 IDE 內置功能 IntelliJ IDEA IntelliJ IDEA 提供了對 MyBatis …

計算機視覺行業洞察--影像行業系列第一期

計算機視覺行業產業鏈的上下游構成相對清晰&#xff0c;從基礎技術研發到具體應用場景的多個環節相對成熟。 以下是我結合VisionChina經歷和行業龍頭企業對計算機視覺行業產業鏈上下游的拆解總結。 上下游總結 上游產業鏈分為軟硬件兩類&#xff0c;視覺的硬件主要指芯片、…

Spring事務原理 二

在上一篇博文《Spring事務原理 一》中&#xff0c;我們熟悉了Spring聲明式事務的AOP原理&#xff0c;以及事務執行的大體流程。 本文中&#xff0c;介紹了Spring事務的核心組件、傳播行為的源碼實現。下一篇中&#xff0c;我們將結合案例&#xff0c;來講解實戰中有關事務的易…

邏輯函數的神經網絡實現

1.單層感知器實現基本邏輯函數 先給大家拋出一道例題 &#xff08;一&#xff09;種類 a.OR函數 目標&#xff1a;當至少一個輸入為1時&#xff0c;輸出1&#xff1b;否則輸出0。 權重設置&#xff1a; 輸入權重&#xff1a;所有 wi1&#xff08;i1,2,...,m&#xff09;。…

SF-HCI-SAP問題收集1

最近在做HCI的集成&#xff0c;是S4的環境&#xff0c;發現很多東西都跑不通&#xff0c;今天開始收集一下錯誤點 如果下圖沖從0001變成0010&#xff0c;sfiom_rprq_osi表就會存數據&#xff0c;系統檢查到此表就會報錯&#xff0c;這個選項的作用就是自定義信息類型也能更新&a…

(面試經典問題之分布式鎖)分布式鎖的基本原理、作用以及實現

一、什么是分布式鎖 分布式鎖指的是在分布式場景中實現互斥類型的鎖。 分布式是什么意思&#xff1f;分布式表示運行的節點可能在不同的機器或不同的網段中&#xff0c;節點間通信通過socket。互斥類型是什么意思&#xff1f;互斥類型表示同一時刻只允許一個執行體進入臨界資…

機械硬盤與固態硬盤的區別-機械硬盤的未來在哪里?

隨著近年來固態硬盤的技術成熟和成本的下探&#xff0c;固態硬盤&#xff08;SSD&#xff09;儼然有要取代傳統機械硬盤&#xff08;HDD&#xff09;的趨勢&#xff0c;但目前單位容量下機械硬盤每GB價格相比閃存還有5-7倍的優勢&#xff0c;那么機械硬盤是否已經發展到極限&am…

06排序 + 查找(D1_排序(D1_基礎學習))

目錄 學習預熱&#xff1a;基礎知識 一、什么是排序 二、為什么要排序 三、排序的穩定性 四、排序穩定性的意義 五、排序分類方式 方式一&#xff1a;內外分類 方式二&#xff1a;比較分類 六、排序算法性能評估 1. 算法的時間復雜度 2. 算法的空間復雜度 七、知識小…

簡訊:Rust 2024 edition and v1.85.0 已發布

詳見 https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html 升級方法&#xff1a;rustup update stable

Python 錯誤和異常處理

目錄 try-except塊 例子&#xff1a; 輸出&#xff1a; 捕獲多種異常 例子&#xff1a; else和finally 例子&#xff1a; 輸出&#xff1a; 自定義異常 例子&#xff1a; 輸出&#xff1a; 好的&#xff0c;簡單來說&#xff0c;錯誤和異常處理是編程中用來處理程序…

Linux系統使用Docker部署Geoserver并做數據掛載進行地圖服務的發布和游覽

文章目錄 1、前提環境2、拉取geoserver鏡像3、創建數據掛載目錄4、 運行容器5、 測試使用&#xff08;發布shp數據為服務&#xff09;5.1、創建工作區5.2、添加數據存儲5.3、發布圖層5.4、服務游覽 1、前提環境 部署環境&#xff1a;Linux&#xff0c;Centos7 &#xff0c;Doc…

Innovus中快速獲取timing path邏輯深度的golden腳本

在實際項目中我們經常會遇到一條timing path級數特別多&#xff0c;可能是一兩頁都翻不完。此時&#xff0c;我們大都需要手工去數這條path上到底有哪些是設計本身的邏輯&#xff0c;哪些是PR工具插入的buffer和inverter。 數字IC后端手把手培訓教程 | Clock Gating相關clock …

Python爬蟲實戰:從零到一構建數據采集系統

文章目錄 前言一、準備工作1.1 環境配置1.2 選擇目標網站 二、爬蟲實現步驟2.1 獲取網頁內容2.2 解析HTML2.3 數據保存 三、完整代碼示例四、優化與擴展4.1 反爬應對策略4.2 動態頁面處理4.3 數據可視化擴展 五、注意事項六、總結互動環節 前言 在大數據時代&#xff0c;數據采…

SpringBoot中實現限流和熔斷功能

我們將使用Java的ScheduledExecutorService來實現一個簡單的令牌桶算法(Token Bucket Algorithm),并結合一個自定義的服務類來處理第三方API調用。 1. 創建限流器 首先,創建一個簡單的限流器類: import java.util.concurrent.*;public class SimpleRateLimiter {

如何使用Python快速開發一個帶管理系統界面的網站-解析方案

如果你想用 Python 開發一個 管理系統界面 的網站&#xff0c;并且希望界面美觀&#xff0c;可以考慮以下幾個框架和庫&#xff1a; 1. Streamlit&#xff08;快速、簡潔&#xff09; 適合&#xff1a;數據分析、儀表盤、內部管理系統特點&#xff1a; 寫法簡單&#xff0c;類…