1. 使用文档
Spring Cloud CircuitBreaker 项目包含 Resilience4J 和 Spring Retry 的实现。Spring Cloud CircuitBreaker 中实现的 API 位于 Spring Cloud Commons 中。这些 API 的使用文档位于 Spring Cloud Commons 文档。
1.1. 配置 Resilience4J 熔断器
1.1.1. 入门依赖
Resilience4J 实现有两个Starters,一个用于响应式应用,另一个用于非响应式应用。
-
org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j- 非响应式应用程序 -
org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j- 响应式应用程序
1.1.2. 自动配置
您可以将 Resilience4J 自动配置禁用,方法是将 spring.cloud.circuitbreaker.resilience4j.enabled 设置为 false。
1.1.3. 默认配置
要为所有断路器提供默认配置,请创建一个 Customize Bean,并传入一个 Resilience4JCircuitBreakerFactory 或 ReactiveResilience4JCircuitBreakerFactory。可以通过 configureDefault 方法来提供默认配置。
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() {
return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build())
.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
.build());
}
响应式示例
@Bean
public Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() {
return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()).build());
}
自定义 ExecutorService
如果您希望配置执行断路器的 ExecutorService,可以使用 Resilience4JCircuitBreakerFactor 进行配置。
例如,如果您希望使用一个上下文感知的 ExecutorService,您可以执行以下操作。
@Bean
public Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() {
return factory -> {
ContextAwareScheduledThreadPoolExecutor executor = ContextAwareScheduledThreadPoolExecutor.newScheduledThreadPool().corePoolSize(5)
.build();
factory.configureExecutorService(executor);
};
}
1.1.4. 具体的断路器配置
类似于提供默认配置,您可以创建一个 Customize Bean,该 Bean 接收一个 Resilience4JCircuitBreakerFactory 或 ReactiveResilience4JCircuitBreakerFactory。
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> slowCustomizer() {
return factory -> factory.configure(builder -> builder.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(2)).build()), "slow");
}
除了配置所创建的断路器外,您还可以在断路器创建完成后、返回调用方之前对其进行自定义。要实现这一点,您可以使用 addCircuitBreakerCustomizer 方法。这有助于为 Resilience4J 断路器添加事件处理器。
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> slowCustomizer() {
return factory -> factory.addCircuitBreakerCustomizer(circuitBreaker -> circuitBreaker.getEventPublisher()
.onError(normalFluxErrorConsumer).onSuccess(normalFluxSuccessConsumer), "normalflux");
}
响应式示例
@Bean
public Customizer<ReactiveResilience4JCircuitBreakerFactory> slowCustomizer() {
return factory -> {
factory.configure(builder -> builder
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(2)).build())
.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()), "slow", "slowflux");
factory.addCircuitBreakerCustomizer(circuitBreaker -> circuitBreaker.getEventPublisher()
.onError(normalFluxErrorConsumer).onSuccess(normalFluxSuccessConsumer), "normalflux");
};
}
1.1.5. 熔断器属性配置
您可以在应用程序的配置属性文件中配置 CircuitBreaker 和 TimeLimiter 个实例。属性配置的优先级高于 Java Customizer 配置。
resilience4j.circuitbreaker:
instances:
backendA:
registerHealthIndicator: true
slidingWindowSize: 100
backendB:
registerHealthIndicator: true
slidingWindowSize: 10
permittedNumberOfCallsInHalfOpenState: 3
slidingWindowType: TIME_BASED
recordFailurePredicate: io.github.robwin.exception.RecordFailurePredicate
resilience4j.timelimiter:
instances:
backendA:
timeoutDuration: 2s
cancelRunningFuture: true
backendB:
timeoutDuration: 1s
cancelRunningFuture: false
有关 Resilience4j 属性配置的更多信息,请参阅 Resilience4J Spring Boot 2 配置。
1.1.6. 支持舱壁模式(Bulkhead pattern)
如果 resilience4j-bulkhead 在类路径中,Spring Cloud CircuitBreaker 将为所有方法添加 Resilience4j 限流器(Bulkhead)封装。您可以通过将 spring.cloud.circuitbreaker.bulkhead.resilience4j.enabled 设置为 false 来禁用 Resilience4j 限流器(Bulkhead)。
Spring Cloud CircuitBreaker Resilience4j 提供了熔断模式的两种实现:
-
a
SemaphoreBulkheadwhich uses Semaphores -
a
FixedThreadPoolBulkheadwhich uses a bounded queue and a fixed thread pool.
默认情况下,Spring Cloud CircuitBreaker Resilience4j 使用 FixedThreadPoolBulkhead。若要将默认行为修改为使用 SemaphoreBulkhead,请将属性 spring.cloud.circuitbreaker.resilience4j.enableSemaphoreDefaultBulkhead 设置为 true。
有关批量隔离模式实现的更多信息,请参阅 Resilience4j 批量隔离。
代码 Customizer<Resilience4jBulkheadProvider> 可用于提供默认的 Bulkhead 和 ThreadPoolBulkhead 配置。
@Bean
public Customizer<Resilience4jBulkheadProvider> defaultBulkheadCustomizer() {
return provider -> provider.configureDefault(id -> new Resilience4jBulkheadConfigurationBuilder()
.bulkheadConfig(BulkheadConfig.custom().maxConcurrentCalls(4).build())
.threadPoolBulkheadConfig(ThreadPoolBulkheadConfig.custom().coreThreadPoolSize(1).maxThreadPoolSize(1).build())
.build()
);
}
1.1.7. 特定的舱壁配置
类似于证明默认的 'Bulkhead' 或 'ThreadPoolBulkhead' 配置,您可以通过创建一个 Customize Bean 来实现,该 Bean 接收一个 Resilience4jBulkheadProvider。
@Bean
public Customizer<Resilience4jBulkheadProvider> slowBulkheadProviderCustomizer() {
return provider -> provider.configure(builder -> builder
.bulkheadConfig(BulkheadConfig.custom().maxConcurrentCalls(1).build())
.threadPoolBulkheadConfig(ThreadPoolBulkheadConfig.ofDefaults()), "slowBulkhead");
}
除了配置所创建的隔离舱(Bulkhead)之外,您还可以在隔离舱和线程池隔离舱被创建之后、返回给调用者之前对其进行自定义。为此,您可以使用 addBulkheadCustomizer 和 addThreadPoolBulkheadCustomizer 方法。
舱壁示例
@Bean
public Customizer<Resilience4jBulkheadProvider> customizer() {
return provider -> provider.addBulkheadCustomizer(bulkhead -> bulkhead.getEventPublisher()
.onCallRejected(slowRejectedConsumer)
.onCallFinished(slowFinishedConsumer), "slowBulkhead");
}
线程池舱壁示例
@Bean
public Customizer<Resilience4jBulkheadProvider> slowThreadPoolBulkheadCustomizer() {
return provider -> provider.addThreadPoolBulkheadCustomizer(threadPoolBulkhead -> threadPoolBulkhead.getEventPublisher()
.onCallRejected(slowThreadPoolRejectedConsumer)
.onCallFinished(slowThreadPoolFinishedConsumer), "slowThreadPoolBulkhead");
}
1.1.8. 熔断器属性配置
您可以在应用程序的配置属性文件中配置 ThreadPoolBulkhead 和 SemaphoreBulkhead 实例。属性配置的优先级高于 Java Customizer 配置。
resilience4j.thread-pool-bulkhead:
instances:
backendA:
maxThreadPoolSize: 1
coreThreadPoolSize: 1
resilience4j.bulkhead:
instances:
backendB:
maxConcurrentCalls: 10
有关 Resilience4j 属性配置的更多信息,请参阅 Resilience4J Spring Boot 2 配置。
1.1.9. 收集指标
Spring Cloud Circuit Breaker Resilience4j 包含自动配置,以在类路径中包含正确依赖项时设置指标收集。要启用指标收集,您必须包含 org.springframework.boot:spring-boot-starter-actuator 和 io.github.resilience4j:resilience4j-micrometer。有关这些依赖项存在时生成的指标的更多信息,请参阅 Resilience4j 文档。
您无需直接包含 micrometer-core,因为它由 spring-boot-starter-actuator 自动引入。 |
1.2. 配置 Spring 重试熔断器
Spring Retry 为 Spring 应用程序提供了声明式的重试支持。
该项目的一个子集包含实现断路器功能的能力。
Spring Retry 通过其 CircuitBreakerRetryPolicy 与一个 有状态重试 的组合,提供了一个断路器实现。
所有使用 Spring Retry 创建的断路器都将基于 CircuitBreakerRetryPolicy 和一个 DefaultRetryState 创建。
这两个类均可通过 SpringRetryConfigBuilder 进行配置。
1.2.1. 默认配置
要为所有断路器提供默认配置,请创建一个 Customize Bean,并将其传递一个 SpringRetryCircuitBreakerFactory。 configureDefault 方法可用于提供默认配置。
@Bean
public Customizer<SpringRetryCircuitBreakerFactory> defaultCustomizer() {
return factory -> factory.configureDefault(id -> new SpringRetryConfigBuilder(id)
.retryPolicy(new TimeoutRetryPolicy()).build());
}
1.2.2. 特定断路器配置
类似于提供默认配置,您可以创建一个 Customize Bean,该 Bean 接收一个 SpringRetryCircuitBreakerFactory。
@Bean
public Customizer<SpringRetryCircuitBreakerFactory> slowCustomizer() {
return factory -> factory.configure(builder -> builder.retryPolicy(new SimpleRetryPolicy(1)).build(), "slow");
}
除了配置所创建的断路器外,您还可以在断路器创建完成后、返回调用方之前对其进行自定义。为此,您可以使用 addRetryTemplateCustomizers 方法。这有助于为 RetryTemplate 添加事件处理器。
@Bean
public Customizer<SpringRetryCircuitBreakerFactory> slowCustomizer() {
return factory -> factory.addRetryTemplateCustomizers(retryTemplate -> retryTemplate.registerListener(new RetryListener() {
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
return false;
}
@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
}
}));
}