Spring Cloud CircuitBreaker 提供了跨不同断路器实现的抽象。它提供了在您的应用程序中使用的一致 API,让您(开发人员)选择最适合您的应用程序需求的断路器实现。
Spring Cloud CircuitBreaker 项目包含 Resilience4J 和 Spring Retry 的实现。Spring Cloud CircuitBreaker 中实现的 API 位于 Spring Cloud Commons 中。
Spring Cloud 支持一下几种 CircuitBreaker
Resilience4J
Sentinel
Spring Retry
下文主要描述 Resilience4J 的使用
Resilience4J 介绍
Resilience4J 其实是参照 Netfix Hystrix 实现的的断路器
断路器 本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似保险熔断),向调用方法返回一个符合预期的,可处理的被选相应(FallBack), 而不是长时间的等待或者跑出调用方法无法处理的异常,这样就保证了服务调用方的线程不会长时间,不必要地占用,从而避免了故障在分布式系统中进行蔓延,从而导致雪崩效应。
Resilience4J 实现有两种 starter
,一种用于 reactor 方式的依赖,另一种用于非 reactor 的 starter
。
依赖如下:
org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j
普通模式
org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j
reactor 模式
reactor
模式的依赖可以配合 spring cloud gateway
使用
使用配置
默认配置
要为所有断路器提供默认配置,我们需要创建一个自定义 bean,该 bean被传递给Resilience4JCuitBreakerFactory 或 ReactiveResilience4JCuitBreakerFactory。
configureDefault 方法可用于提供默认配置。
@Bean public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() { return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id) // 默认超时时间 4s .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()) // circuitBreaker 使用默认配置 .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()) .build()); }
基于 YML 方式的配置
下面是断路器和时间限流配配置:
# 断路器配置 resilience4j.circuitbreaker: instances: # 配置服务 backendA: registerHealthIndicator: true slidingWindowSize: 100 backendB: registerHealthIndicator: true # 滑动窗口类型:COUNT_BASED 基于计数的滑动窗口, TIME_BASED 基于计时的滑动窗口 slidingWindowType: TIME_BASED # 滑动窗口大小 slidingWindowSize: 10 # 当 circuitbreaker 处于 HalfOpen 允许通过的请求数量 permittedNumberOfCallsInHalfOpenState: 3 recordFailurePredicate: io.github.robwin.exception.RecordFailurePredicate # 时间限流 resilience4j.timelimiter: instances: backendA: timeoutDuration: 2s cancelRunningFuture: true backendB: timeoutDuration: 1s cancelRunningFuture: false
Bulkhead 配置
Bulkhead作用是让一个应用中不同方法互不影响,避免某些方法调用异常危及整个应用。
Java 方式的配置
@Bean public Customizer<Resilience4jBulkheadProvider> slowBulkheadProviderCustomizer() { return provider -> provider.configure(builder -> builder .bulkheadConfig(BulkheadConfig.custom().maxConcurrentCalls(1).build()) .threadPoolBulkheadConfig(ThreadPoolBulkheadConfig.ofDefaults()), "slowBulkhead"); }
YML 方式的配置
resilience4j.thread-pool-bulkhead: instances: backendA: # 配置最大线程数 maxThreadPoolSize: 1 # 核心线程数 coreThreadPoolSize: 1 resilience4j.bulkhead: instances: backendB: maxConcurrentCalls: 10
举个例子
首先我们下先加入 gradle 的依赖
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j'
我们需要配置 feign 使用 circuitbreaker
yml 配置文件如下:
feign: circuitbreaker: enabled: true resilience4j.timelimiter: instances: default: timeoutDuration: 1s cancelRunningFuture: true
如果通过 Fegin 调用 payment-service
服务 /payment/create
feign 代码如下:
@FeignClient(name = "payment-service", path = "/payment") public interface PaymentFeign { @PostMapping("/create") PaymentVo create(@RequestBody @Validated PaymentDto paymentDto); }
如果超时会出现一下错误: