当使用微服务架构来构建我们的应用程序时,在服务中最终会得到一个非常复杂的依赖树。如果依赖关系树中的服务遇到导致其开始缓慢响应的问题,则最终会形成一系列问题,这些问题会使依赖关系树级联起来。随着越来越多的请求进入应用程序,等待慢速服务响应可能会消耗越来越多的资源。更糟糕的是,对慢速服务施加的额外负载可能会加剧问题。为了帮助减轻这些类型的级联故障的影响,通常的做法是使用断路器作为微服务应用的一部分。
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 Overflow和Gitter或通过创建GitHub问题与我们联系。