配置框架 Retry 斷路器
Spring Framework 7 引入了原生的重試支援,作為框架彈性特性的一部分。Spring Cloud CircuitBreaker 提供了一個斷路器實現,該實現使用 Spring Framework 的 RetryTemplate 和 RetryPolicy API。
與 Spring Framework 的無狀態重試支援不同,此實現透過跟蹤故障並實現斷路器模式(關閉、開啟和半開狀態)來新增有狀態的斷路器功能。該實現是按照 Spring Retry 的 CircuitBreakerRetryPolicy 建模的,其中斷路器在單個執行失敗後(所有重試耗盡)開啟,而不是計算單個重試嘗試。
啟動器
要使用 Framework Retry 斷路器實現,請將以下啟動器新增到您的專案中
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-framework-retry</artifactId>
</dependency>
implementation 'spring-cloud-starter-circuitbreaker-framework-retry'
預設配置
要為所有斷路器提供預設配置,請建立一個 Customizer bean,該 bean 傳入一個 FrameworkRetryCircuitBreakerFactory。configureDefault 方法可用於提供預設配置。
@Bean
public Customizer<FrameworkRetryCircuitBreakerFactory> defaultCustomizer() {
return factory -> factory.configureDefault(id -> new FrameworkRetryConfigBuilder(id)
.retryPolicy(RetryPolicy.withMaxRetries(3))
.openTimeout(Duration.ofSeconds(20))
.resetTimeout(Duration.ofSeconds(5))
.build());
}
特定斷路器配置
與提供預設配置類似,您可以建立一個 Customizer bean,該 bean 傳入一個 FrameworkRetryCircuitBreakerFactory 來配置特定的斷路器。
@Bean
public Customizer<FrameworkRetryCircuitBreakerFactory> slowCustomizer() {
return factory -> factory.configure(builder -> builder
.retryPolicy(RetryPolicy.withMaxRetries(1))
.openTimeout(Duration.ofSeconds(30))
.resetTimeout(Duration.ofSeconds(10))
.build(), "slow");
}
重試策略
Spring Framework 7 提供了幾種內建的重試策略,可以與 Framework Retry 斷路器一起使用
-
RetryPolicy.withMaxRetries(int)- 重試固定次數 -
RetryPolicy.withMaxDuration(Duration)- 重試直到達到最大持續時間 -
RetryPolicy.withBackoff(Duration, double)- 以指數退避方式重試 -
RetryPolicy.forExceptions(Class<?>…)- 僅針對特定異常型別重試
您還可以使用 and() 和 or() 運算子組合策略
@Bean
public Customizer<FrameworkRetryCircuitBreakerFactory> customRetryPolicy() {
return factory -> factory.configureDefault(id -> new FrameworkRetryConfigBuilder(id)
.retryPolicy(RetryPolicy.withMaxRetries(3)
.and(RetryPolicy.withMaxDuration(Duration.ofSeconds(5)))
.forExceptions(IOException.class, TimeoutException.class))
.build());
}
斷路器行為
Framework Retry 斷路器實現遵循 Spring Retry 斷路器模式
-
關閉狀態:請求被允許透過並根據配置的
RetryPolicy進行重試。當一個完整的呼叫失敗時(所有重試耗盡),斷路器立即開啟。 -
開啟狀態:請求立即失敗並返回回退響應,不嘗試重試。在
openTimeout期限後,斷路器轉換為半開狀態。 -
半開狀態:允許單個請求透過以測試服務是否已恢復。如果成功,斷路器關閉。如果失敗,斷路器重新開啟。
-
重置超時:如果在
resetTimeout期限內沒有發生故障,斷路器會自動重置為關閉狀態,即使它之前是開啟的。
使用示例
以下是使用 Framework Retry 斷路器的完整示例
@Service
public class BookService {
private final CircuitBreakerFactory circuitBreakerFactory;
private final RestTemplate restTemplate;
public BookService(CircuitBreakerFactory circuitBreakerFactory, RestTemplate restTemplate) {
this.circuitBreakerFactory = circuitBreakerFactory;
this.restTemplate = restTemplate;
}
public String getBookTitle(Long bookId) {
CircuitBreaker circuitBreaker = circuitBreakerFactory.create("bookService");
return circuitBreaker.run(
() -> restTemplate.getForObject("/books/" + bookId, String.class),
throwable -> "Fallback Book"
);
}
}
配置示例
@Configuration
public class CircuitBreakerConfiguration {
@Bean
public Customizer<FrameworkRetryCircuitBreakerFactory> defaultCustomizer() {
return factory -> {
// Default configuration for all circuit breakers
factory.configureDefault(id -> new FrameworkRetryConfigBuilder(id)
.retryPolicy(RetryPolicy.withMaxRetries(3)
.withBackoff(Duration.ofMillis(100), 2.0))
.openTimeout(Duration.ofSeconds(20))
.resetTimeout(Duration.ofSeconds(5))
.build());
};
}
@Bean
public Customizer<FrameworkRetryCircuitBreakerFactory> specificCustomizer() {
return factory -> {
// Specific configuration for "slow" circuit breaker
factory.configure(builder -> builder
.retryPolicy(RetryPolicy.withMaxRetries(1))
.openTimeout(Duration.ofSeconds(30))
.resetTimeout(Duration.ofSeconds(10))
.build(), "slow");
// Specific configuration for "critical" circuit breaker
factory.configure(builder -> builder
.retryPolicy(RetryPolicy.withMaxRetries(5))
.openTimeout(Duration.ofMinutes(2))
.resetTimeout(Duration.ofSeconds(15))
.build(), "critical");
};
}
}