请使用 Spring Cloud Commons 5.0.1 获取最新稳定版本!spring-doc.cadn.net.cn

Spring Cloud Circuit Breaker

Spring Cloud Circuit Breaker 提供了跨不同断路器实现的抽象。它为您的应用程序提供了一致的 API,让您(开发者)能够根据自身应用需求选择最适合的断路器实现。spring-doc.cadn.net.cn

核心概念

要在您的代码中创建断路器,可以使用 CircuitBreakerFactory API。当您在类路径中包含 Spring Cloud Circuit Breaker Starters时,系统会自动为您创建一个实现此 API 的 Bean。
以下示例展示了如何使用此 API 的简单示例:spring-doc.cadn.net.cn

@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 是当熔断器触发时所执行的回退(fallback)逻辑。
该函数会接收导致回退被触发的 Throwable(即异常或错误信息)。
您可以选择性地省略回退逻辑,如果您不希望提供回退处理。spring-doc.cadn.net.cn

断路器在响应式代码中

如果 Project Reactor 在类路径中,您还可以在响应式代码中使用 ReactiveCircuitBreakerFactory。以下示例展示了如何实现此操作:spring-doc.cadn.net.cn

@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 方法接收一个 MonoFlux,并将其封装在断路器中。您可以选择对备用方法 Function 进行性能分析,当断路器被触发时将调用此方法,并将导致失败的 Throwable 作为参数传入。spring-doc.cadn.net.cn

配置

您可以通过创建类型为 Customizer 的 Bean 来配置熔断器。 Customizer 接口包含一个单一方法(称为 customize),该方法用于自定义 Objectspring-doc.cadn.net.cn

有关如何自定义特定实现的详细信息,请参阅以下文档:spring-doc.cadn.net.cn

某些 CircuitBreaker 实现(例如 Resilience4JCircuitBreaker)在每次调用 CircuitBreaker#run 时都会调用 customize 方法。这可能会导致效率低下。此时,您可以使用 CircuitBreaker#once 方法。该方法在多次调用 customize 没有意义的情况下非常有用,例如在 消费 Resilience4j 的事件 时。spring-doc.cadn.net.cn

以下示例展示了每个io.github.resilience4j.circuitbreaker.CircuitBreaker消耗事件的方式。spring-doc.cadn.net.cn

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