配置框架重试断路器
Spring Framework 7 引入了原生重试支持,作为框架弹性特性的一部分。Spring Cloud CircuitBreaker 提供了一个使用 Spring Framework 的断路器实现重试模板和RetryPolicy蜜蜂属。
与 Spring Framework 的无状态重试支持不同,该实现通过跟踪故障和实现断路器模式,增加了有状态的断路器功能(闭合、开启和半开状态)。该实现以 Spring Retry 的CircuitBreakerRetry策略,其中电路在一次失败执行后打开(所有重试耗尽),而不是计算单个重试次数。
首先
要使用Framework Retry断路器实现,请在您的项目中添加以下起始工具:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-framework-retry</artifactId>
</dependency>
implementation 'spring-cloud-starter-circuitbreaker-framework-retry'
默认配置
要为所有断路器提供默认配置,请创建定制器传递给 a 的豆子框架RetryCircuitBreakerFactory. 这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());
}
特定断路器配置
类似于提供默认配置,你可以创建定制器传递给 a 的豆子框架RetryCircuitBreakerFactory配置特定的断路器。
@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(持续时间,双倍)- 带指数退回的重试 -
RetryPolicy.forExceptions(Class<?>...)- 仅针对特定例外类型进行重试
你也可以用以下方式合并保单并且()和或者()运营商:
@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");
};
}
}