介绍 Spring Cloud 断路器

工程 | Ryan Baxter | 2019年4月16日 | ...

背景

在使用微服务架构构建应用程序时,服务之间常常会形成相当复杂的依赖树。如果依赖树下游的服务遇到问题导致响应速度变慢,就会导致一系列问题级联向上游传播。随着越来越多的请求进入应用程序,等待慢速服务响应可能会消耗越来越多的资源。更糟糕的是,慢速服务上的额外负载可能会加剧问题。为了减轻这类级联故障的影响,通常的做法是在微服务应用程序中使用断路器

Spring Cloud 允许开发人员通过使用Netflix Hystrix(作为Spring Cloud Netflix 项目的一部分)将其应用程序中添加断路器。除了 Hystrix 之外,Spring Cloud 开发人员可能还希望使用其他断路器实现。为了帮助 Spring Cloud 开发人员以一致的方式向其应用程序添加断路器,我们在 Spring Cloud 孵化器中引入了Spring Cloud Circuit Breaker 项目

关于

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

大多数实现也支持响应式 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"));
                });
	}
}

配置断路器

在大多数情况下,您需要配置断路器的行为。为此,您可以创建 `Customizer` 类型的 Bean。Spring Cloud Circuit Breaker 允许您为所有断路器提供默认配置,以及为特定断路器提供配置。例如,在使用 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 问题

获取 Spring Newsletter

保持与 Spring Newsletter 的联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring在一个简单的订阅中提供对OpenJDK™、Spring 和 Apache Tomcat®的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部