Spring Cloud Circuit Breaker

Spring Cloud 断路器为不同的断路器实现提供了抽象。它提供了一致的 API 供您的应用程序使用,让开发人员可以选择最适合其应用程序需求的断路器实现。

支持的实现

Spring Cloud 支持以下断路器实现

核心概念

要在代码中创建断路器,可以使用 CircuitBreakerFactory API。当您在类路径中包含 Spring Cloud 断路器 starter 时,会自动为您创建一个实现此 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。如果您不想提供备用方法,可以选择排除它。

响应式代码中的断路器

如果 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,如果断路器跳闸,它将被调用,并传递导致故障的 Throwable

配置

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

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

某些 CircuitBreaker 实现,例如 Resilience4JCircuitBreaker,每次调用 CircuitBreaker#run 时都会调用 customize 方法。这可能会效率低下。在这种情况下,您可以使用 CircuitBreaker#once 方法。这在多次调用 customize 没有意义的情况下很有用,例如,在 消费 Resilience4j 的事件 的情况下。

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

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

Spring HTTP 服务客户端支持

Spring Cloud 通过以下配置器支持 Spring HTTP 服务客户端集成

  • CircuitBreakerRestClientHttpServiceGroupConfigurer

  • CircuitBreakerWebClientHttpServiceGroupConfigurer

这些配置器为 Spring HTTP 服务客户端组 启用断路器支持。

当使用 @HttpServiceFallbackAnnotation 配置备用类时,会添加断路器适配器装饰器:- CircuitBreakerAdapterDecorator 用于 RestClient - ReactiveCircuitBreakerAdapterDecorator 用于 WebClient

您可以通过设置相应的属性来禁用 HTTP 服务客户端的断路器集成

  • 对于阻塞 (RestClient) 客户端:spring.cloud.circuitbreaker.http-services.enabled=false

  • 对于响应式 (WebClient) 客户端:spring.cloud.circuitbreaker.reactive-http-services.enabled=false

这会阻止断路器装饰器应用于基于接口的 HTTP 客户端组。

使用注解声明备用

备用通过配置类上的 @HttpServiceFallback 注解进行配置。此注解允许您声明

  • 备用实现类(通过 value

  • 备用支持的服务接口(通过 forService,可选)

  • 备用适用的组(通过 forGroup,可选)

可以使用 Java 的 @Repeatable 注解机制在同一个类上声明多个 @HttpServiceFallback 注解。如果未指定组,则备用适用于所有没有给定服务接口的显式每组备用的组。

备用类按以下优先级解析

  1. 同时匹配 forServiceforGroup 的备用类

  2. 匹配 forService 但没有 forGroup 的备用类(服务的全局备用)

  3. 既没有 forService 也没有 forGroup 的备用类(组中所有服务或全局的默认备用)

示例

@HttpServiceFallback(value = DefaultFallbacks.class)
@HttpServiceFallback(value = GroupAndServiceSpecificFallbacks.class, service = {BillingService.class, ShippingService.class}, group = "billing")
public class MyFallbackConfig {
    ...
}

此配置导致

  • DefaultFallbacks 用作所有未明确处理的服务的全局备用

  • GroupAndServiceSpecificFallbacks 仅用于 "billing" 组中的 BillingServiceShippingService

  • 备用类及其方法必须是 public

  • 备用方法不得使用 @HttpExchange 注解

断路器适配器的工作原理

适配器使用断路器逻辑封装 @HttpExchange 方法调用。当备用被触发时,使用用户定义的备用类创建一个代理。通过匹配选择适当的备用方法

  • 具有相同名称和参数类型的方法,或

  • 具有相同名称和参数类型,前面带有一个 Throwable 参数(用于访问失败原因)的方法

给定以下接口

@HttpExchange("/test")
public interface TestService {

    @GetExchange("/{id}")
    Person test(@PathVariable UUID id);

    @GetExchange
    String test();
}

匹配的备用类可以是

public class TestServiceFallback {

    public Person test(UUID id);

    public String test(Throwable cause);
}
© . This site is unofficial and not affiliated with VMware.