介绍Spring Cloud断路器


当使用微服务架构来构建我们的应用程序时,在服务中最终会得到一个非常复杂的依赖树。如果依赖关系树中的服务遇到导致其开始缓慢响应的问题,则最终会形成一系列问题,这些问题会使依赖关系树级联起来。随着越来越多的请求进入应用程序,等待慢速服务响应可能会消耗越来越多的资源。更糟糕的是,对慢速服务施加的额外负载可能会加剧问题。为了帮助减轻这些类型的级联故障的影响,通常的做法是使用断路器作为微服务应用的一部分。
Spring Cloud 允许开发人员使用Netflix Hystrix作为Spring Cloud Netflix项目的一部分,为其应用添加断路器。除了Hystrix之外,Spring Cloud开发人员可能还想使用其他断路器实现。为了帮助Spring Cloud开发人员以一致的方式为其应用程序添加断路器,我们引入了Spring Cloud Circuit Breaker项目作为Spring Cloud孵化器的一部分。
Spring Cloud Circuit Breaker项目提供了一个抽象API,用于为您的应用添加断路器。在本博文发布时,有四种支持的实现:

要使用想要指定的实现,请将适当的启动器添加到应用程序的类路径中。

使用Spring Cloud断路器
目前,Spring Cloud Circuit Breaker不是Spring Cloud BOM的一部分,仅发布到我们的快照仓库。您需要将我们的快照仓库添加到Maven或Gradle文件中。以下示例使用Maven:

<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/libs-snapshot-local</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
</repositories>

接下来,您需要将Spring Cloud Circuit Breaker依赖项添加到您的应用程序中。同样,以下示例使用Maven:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>
            spring-cloud-starter-circuitbreaker-resilience4j
       </artifactId>
        <version>0.0.1.BUILD-SNAPSHOT</version>
    </dependency>
</dependencies>

Spring Cloud Circuit Breaker CircuitBreakerFactory根据应用程序类路径上的启动器自动配置实现。然后,您可以将此接口注入到所需的任何类中。以下示例显示了如何执行此操作:

@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");
    }
}

大多数实现还支持Reactive API。目前,Spring Retry是唯一的没有反应式实现。如果要在断路器中包含一些代反应式码,则需要使用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 -> {
            CircuitBreaker cb = cbFactory.create(
"slow");
            return cb.run(it, throwable -> 
                            Mono.just(
"fallback"));
                });
    }
}

配置断路器
在大多数情况下,您将需要配置断路器的行为。为此,您可以创建类型的bean Customizer。Spring Cloud断路器允许您为所有断路器提供默认配置以及特定断路器的配置。例如,要在使用Resilience4J时为所有断路器提供默认配置,您可以将以下bean添加到配置类:

@Bean
public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() {
    return factory -> factory.configureDefault(
            id -> new Resilience4JConfigBuilder(id)
            .timeLimiterConfig(TimeLimiterConfig.custom()
                .timeoutDuration(Duration.ofSeconds(4)).build())
            .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
            .build());
}

配置单个断路器的代码和上面看起来非常相似,另外您需要在Customizer其中提供断路器ID ,如下所示:

@Bean
public Customizer<Resilience4JCircuitBreakerFactory> slowCustomizer() {
    return factory -> factory.configure(builder -> {
        return builder
            .timeLimiterConfig(TimeLimiterConfig.custom()
                            .timeoutDuration(Duration.ofSeconds(2)).build())
            .circuitBreakerConfig(
                            CircuitBreakerConfig.ofDefaults());
    }, "slow");
}

我们期待听到您对这个新项目的看法。查看GitHub项目以及文档以获取更多信息。与往常一样,您可以通过Stack OverflowGitter或通过创建GitHub问题与我们联系