配置框架 Retry 斷路器

Spring Framework 7 引入了原生的重試支援,作為框架彈性特性的一部分。Spring Cloud CircuitBreaker 提供了一個斷路器實現,該實現使用 Spring Framework 的 RetryTemplateRetryPolicy API。

與 Spring Framework 的無狀態重試支援不同,此實現透過跟蹤故障並實現斷路器模式(關閉、開啟和半開狀態)來新增有狀態的斷路器功能。該實現是按照 Spring Retry 的 CircuitBreakerRetryPolicy 建模的,其中斷路器在單個執行失敗後(所有重試耗盡)開啟,而不是計算單個重試嘗試。

啟動器

要使用 Framework Retry 斷路器實現,請將以下啟動器新增到您的專案中

Maven
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-circuitbreaker-framework-retry</artifactId>
</dependency>
Gradle
implementation 'spring-cloud-starter-circuitbreaker-framework-retry'

預設配置

要為所有斷路器提供預設配置,請建立一個 Customizer bean,該 bean 傳入一個 FrameworkRetryCircuitBreakerFactoryconfigureDefault 方法可用於提供預設配置。

@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());
}

配置選項

FrameworkRetryConfigBuilder 提供以下配置選項

  • retryPolicy(RetryPolicy) - 用於重試的 Spring Framework RetryPolicy。這決定了重試的次數和條件。

  • openTimeout(Duration) - 斷路器在轉換為半開狀態之前保持開啟的時間。預設值為 20 秒。

  • resetTimeout(Duration) - 故障後等待的時間,然後重置斷路器狀態。如果在此超時時間內沒有發生故障,斷路器會自動重置為關閉狀態。預設值為 5 秒。

特定斷路器配置

與提供預設配置類似,您可以建立一個 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");
		};
	}
}

響應式支援

Framework Retry 斷路器實現不支援響應式應用程式。如果您需要響應式支援,請改用 Resilience4J 實現。

© . This site is unofficial and not affiliated with VMware.