跳到主要内容
版本:5.0.1

配置框架重试熔断器

DeepSeek V3 中英对照 Configuring Framework Retry Circuit Breakers

Spring Framework 7 引入了原生重试支持,作为框架弹性功能的一部分。Spring Cloud CircuitBreaker 提供了一个断路器实现,该实现使用了 Spring Framework 的 RetryTemplate 和 RetryPolicy API。

与Spring Framework的无状态重试支持不同,此实现通过跟踪失败并实现断路器模式(关闭、打开和半开状态)来添加有状态断路器功能。该实现仿照Spring Retry的CircuitBreakerRetryPolicy,在单次执行失败(所有重试耗尽)后断路器打开,而不是计算单个重试尝试。

入门指南​

要使用框架重试熔断器实现,请将以下启动器添加到您的项目中:

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

配置选项​

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 提供了多种内置的重试策略,可与框架重试断路器配合使用:

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

断路器行为​

框架的重试熔断器实现遵循 Spring Retry 熔断器模式:

  • 关闭状态:允许请求通过,并根据配置的 RetryPolicy 进行重试。当一次完整的调用失败(所有重试耗尽)时,断路器会立即打开。

  • 打开状态:请求立即失败,返回降级响应,不进行重试尝试。经过 openTimeout 时间后,断路器会过渡到半开状态。

  • 半开状态:允许一个请求通过,以测试服务是否已恢复。如果成功,断路器关闭。如果失败,断路器重新打开。

  • 重置超时:如果在 resetTimeout 时间段内没有发生故障,断路器会自动重置为关闭状态,即使它之前处于打开状态。

示例用法​

以下是使用框架重试熔断器的完整示例:

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

响应式支持​

框架的重试熔断器实现不支持响应式应用。如果需要响应式支持,请改用 Resilience4J 实现。