更多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. 最佳實踐
-
明確重試場景:只對臨時性故障使用重試機制,對于業務錯誤或永久性故障應直接失敗。
-
設置合理的重試次數:通常3-5次即可,過多的重試可能會加重系統負擔。
-
使用退避策略:建議使用指數退避策略(ExponentialBackOffPolicy),避免立即重試對系統造成沖擊。
-
添加監控和日志:通過RetryListener記錄重試情況,便于問題排查。
-
設置超時時間:避免重試過程持續時間過長。
5. 總結
Spring Retry為Spring應用提供了強大而靈活的重試機制,既可以通過注解優雅地實現重試,也可以使用RetryTemplate進行更細粒度的控制。在實際應用中,合理使用重試機制可以提高系統的健壯性和可用性。
需要注意的是,重試機制并非萬能藥,在使用時要根據具體場景選擇合適的重試策略,并做好監控和告警,以便及時發現和處理問題。