跳到主要内容

Spring Cloud 断路器

DeepSeek V3 中英对照 Spring Cloud Circuit Breaker

Spring Cloud 断路器提供了跨不同断路器实现的抽象。它为您的应用程序提供了一致的 API,让您作为开发者可以选择最适合您应用需求的断路器实现。

支持的实现

Spring Cloud 支持以下断路器实现:

核心概念

要在代码中创建熔断器,你可以使用 CircuitBreakerFactory API。当你在类路径中包含 Spring Cloud 熔断器启动器时,会自动为你创建一个实现此 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");
}

}
java

CircuitBreakerFactory.create API 创建一个名为 CircuitBreaker 的类的实例。run 方法接受一个 Supplier 和一个 FunctionSupplier 是你将要包装在断路器中的代码。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")));
}
}
java

ReactiveCircuitBreakerFactory.create API 创建一个名为 ReactiveCircuitBreaker 的类的实例。run 方法接受一个 MonoFlux 并将其包装在断路器(circuit breaker)中。你可以选择性地配置一个后备 Function,当断路器被触发时,该函数将被调用,并且会传递导致失败的 Throwable

配置

你可以通过创建 Customizer 类型的 bean 来配置你的断路器。Customizer 接口有一个单一的方法(称为 customize),该方法接受要定制的 Object 作为参数。

有关如何自定义给定实现的详细信息,请参阅以下文档:

一些 CircuitBreaker 实现,例如 Resilience4JCircuitBreaker,在每次调用 CircuitBreaker#run 时都会调用 customize 方法。这可能会导致效率低下。在这种情况下,你可以使用 CircuitBreaker#once 方法。这在多次调用 customize 没有意义的情况下非常有用,例如在消费 Resilience4j 发出的事件时。

以下示例展示了每个 io.github.resilience4j.circuitbreaker.CircuitBreaker 消费事件的方式。

Customizer.once(circuitBreaker -> {
circuitBreaker.getEventPublisher()
.onStateTransition(event -> log.info("{}: {}", event.getCircuitBreakerName(), event.getStateTransition()));
}, CircuitBreaker::getName)
java