此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Cloud Commons 4.3.0! |
Spring Cloud 断路器
Spring Cloud 断路器提供了跨不同断路器实现的抽象。 它提供了一个在应用程序中使用的一致 API,使开发人员能够选择最适合应用程序需求的断路器实现。
核心概念
要在代码中创建断路器,您可以使用CircuitBreakerFactory
应用程序接口。当您在类路径上包含 Spring Cloud Circuit Breaker Starters时,会自动为您创建一个实现此 API 的 bean。
以下示例显示了如何使用此 API 的简单示例:
@Service
public static class DemoControllerService {
private RestTemplate rest;
private CircuitBreakerFactory cbFactory;
public DemoControllerService(RestTemplate rest, CircuitBreakerFactory cbFactory) {
this.rest = rest;
this.cbFactory = cbFactory;
}
public String slow() {
return cbFactory.create("slow").run(() -> rest.getForObject("/slow", String.class), throwable -> "fallback");
}
}
这CircuitBreakerFactory.create
API 创建一个名为CircuitBreaker
.
这run
方法采用Supplier
和Function
.
这Supplier
是您要包装在断路器中的代码。
这Function
是断路器跳闸时运行的回退。
函数被传递给Throwable
这导致触发了回退。
如果您不想提供回退,可以选择排除回退。
响应式代码中的断路器
如果 Project Reactor 在类路径上,您还可以使用ReactiveCircuitBreakerFactory
用于您的响应式代码。
以下示例显示了如何执行此作:
@Service
public static class DemoControllerService {
private ReactiveCircuitBreakerFactory cbFactory;
private WebClient webClient;
public DemoControllerService(WebClient webClient, ReactiveCircuitBreakerFactory cbFactory) {
this.webClient = webClient;
this.cbFactory = cbFactory;
}
public Mono<String> slow() {
return webClient.get().uri("/slow").retrieve().bodyToMono(String.class).transform(
it -> cbFactory.create("slow").run(it, throwable -> return Mono.just("fallback")));
}
}
这ReactiveCircuitBreakerFactory.create
API 创建一个名为ReactiveCircuitBreaker
.
这run
方法采用Mono
或Flux
并将其包裹在断路器中。
您可以选择分析回退Function
,如果断路器跳闸并传递Throwable
这导致了失败。
配置
您可以通过创建类型Customizer
.
这Customizer
接口有一个单一的方法(称为customize
)将Object
定制。
有关如何自定义给定实现的详细信息,请参阅 以下文档:
一些CircuitBreaker
实现,例如Resilience4JCircuitBreaker
叫customize
每次的方法CircuitBreaker#run
被称为。
它可能效率低下。在这种情况下,您可以使用CircuitBreaker#once
方法。在调用customize
很多时候说不通,
例如,在使用 Resilience4j 的事件的情况下。
以下示例显示了每个io.github.resilience4j.circuitbreaker.CircuitBreaker
使用事件。
Customizer.once(circuitBreaker -> {
circuitBreaker.getEventPublisher()
.onStateTransition(event -> log.info("{}: {}", event.getCircuitBreakerName(), event.getStateTransition()));
}, CircuitBreaker::getName)