Offer 驾到,掘友接招!我正在参与2022春招系列活动-Debug实录任务,点击查看活动详情。
Spring Cloud CircuitBreaker 提供了跨不同断路器实现的抽象。它提供了在您的应用程序中使用的一致 API,让您(开发人员)选择最适合您的应用程序需求的断路器实现。
Spring Cloud CircuitBreaker 项目包含 Resilience4J 和 Spring Retry 的实现。Spring Cloud CircuitBreaker 中实现的 API 位于 Spring Cloud Commons 中。
Spring Cloud 支持一下几种 CircuitBreaker
Resilience4JSentinelSpring 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-resilience4jreactor 模式
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);
}
如果超时会出现一下错误: