Spring Cloud Circuit Breaker

Spring Cloud 断路器为不同的断路器实现提供了一种抽象。它提供了一致的 API,可在应用程序中使用,令您这款们,作为开发人员,可以选择最适合您应用程序需要的断路器实现。

Supported Implementations

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

Core Concepts

要在代码中创建断路器,您可以使用 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");
	}

}

CircuitBreakerFactory.create API 创建一个名为 CircuitBreaker 的类的实例。run 方法采用一个 Supplier 和一个 FunctionSupplier 是您准备包装在断路器中的代码。Function 是如果断路器跳闸则运行的备用方法。该函数传递了引发此备用方法触发的 Throwable。如果您不想提供备用方法,则可以选择将其排除在外。

Circuit Breakers In Reactive Code

如果类路径上有 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 Profiler,在断路器跳闸时将调用此函数,并且将传递导致失败的 Throwable

Configuration

您可以通过创建 Customizer 类型 的 Bean 来配置断路器。Customizer 接口具有一个(名为 customize)方法,它采用要自定义的 Object

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

一些 CircuitBreaker`实现(例如 `Resilience4JCircuitBreaker)在每次调用 `CircuitBreaker#run`时都会调用 `customize`方法。这可能会效率低下。在这种情况下,可以使用 `CircuitBreaker#once`方法。对于在许多情况下调用 `customize`没有意义的情形(例如,在 consuming Resilience4j’s events的情况下),此方法非常有用。

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

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