4. Spring Cloud 断路器

4.1. 简介

Spring Cloud Circuit Breaker 提供了跨不同断路器实现的抽象。 它提供了一个一致的 API 以在您的应用程序中使用,让您(开发人员)选择最适合您的应用程序需求的断路器实现。spring-doc.cn

4.2. 核心概念

要在代码中创建断路器,您可以使用 API。当您在 Classpath 中包含 Spring Cloud Circuit Breaker Starters时,将自动为您创建实现此 API 的 Bean。 以下示例显示了如何使用此 API 的简单示例:CircuitBreakerFactoryspring-doc.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");
    }

}

API 会创建一个名为 . 该方法采用 a 和 . 这是您将要包装在断路器中的代码。 这是在断路器跳闸时运行的回退。 该函数将传递给导致触发回退的函数。 如果您不想提供回退,则可以选择排除回退。CircuitBreakerFactory.createCircuitBreakerrunSupplierFunctionSupplierFunctionThrowablespring-doc.cn

4.2.1. Reactive Code 中的断路器

如果 Project Reactor 位于 class 路径上,则还可以用于反应式代码。 以下示例显示了如何执行此操作:ReactiveCircuitBreakerFactoryspring-doc.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")));
    }
}

API 会创建一个名为 . 该方法采用 a 或 a 并将其包装在断路器中。 您可以选择分析 fallback ,如果断路器跳闸并传递导致故障的 ,则将调用该 fallback 。ReactiveCircuitBreakerFactory.createReactiveCircuitBreakerrunMonoFluxFunctionThrowablespring-doc.cn

4.3. 配置

您可以通过创建类型为 的 bean 来配置断路器。 该接口有一个方法(称为 ),该方法采用 to 自定义。CustomizerCustomizercustomizeObjectspring-doc.cn

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

一些实现,例如 call method 每次都被调用。 它可能效率低下。在这种情况下,您可以使用 method.在多次调用没有意义的情况下,它很有用, 例如,在使用 Resilience4j 的事件的情况下。CircuitBreakerResilience4JCircuitBreakercustomizeCircuitBreaker#runCircuitBreaker#oncecustomizespring-doc.cn

以下示例显示了每个 API 使用事件的方式。io.github.resilience4j.circuitbreaker.CircuitBreakerspring-doc.cn

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