Spring Cloud Circuit Breaker:断路器模式
·
Spring Cloud Circuit Breaker:断路器模式
Spring Cloud Circuit Breaker:断路器模式
1 概述
断路器模式是分布式系统中关键的容错设计模式,用于防止服务故障的连锁反应(雪崩效应)。其核心思想是监控服务调用的健康状态,并在检测到故障时快速失败,而非继续尝试可能失败的操作。断路器有三种状态:关闭(Closed)、开启(Open)和半开(Half-Open)。
1.1 状态
- 关闭(Closed):正常状态,允许请求通过,统计成功/失败率;
- 开启(Open):熔断状态,拒绝所有请求,直接执行fallback;
- 半开(Half-Open):探测状态,允许少量请求通过,验证服务是否恢复。
在关闭状态,断路器允许请求正常通过;当失败率超过阈值时,断路器开启,快速拒绝请求;经过一段时间后,断路器进入半开状态,允许部分请求通过以探测服务是否恢复。这种状态转换机制有效平衡了系统可用性和故障隔离。
1.2 核心抽象类
核心抽象类包括CircuitBreakerFactory和ReactiveCircuitBreakerFactory,分别用于同步和响应式编程模型。
| 特性 | CircuitBreakerFactory |
ReactiveCircuitBreakerFactory |
|---|---|---|
| 适用场景 | 同步/阻塞式应用(Servlet 栈) | 响应式/非阻塞应用(WebFlux、Gateway) |
| 返回类型 | CircuitBreaker |
ReactiveCircuitBreaker |
| 执行模型 | 阻塞式调用(Thread-per-request) | 非阻塞式(Reactor 模型) |
| 调用方式 | run(Supplier<T>, Function<Throwable, T>) |
run(Mono<T>/Flux<T>, Function<Throwable, Mono<T>/Flux<T>>) |
| 典型技术栈 | Spring MVC + RestTemplate/Feign | Spring WebFlux + WebClient / Spring Cloud Gateway |
| 底层实现 | Resilience4JCircuitBreakerFactory |
ReactiveResilience4JCircuitBreakerFactory |
2 响应式模型断路器示例
2.1 依赖配置
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2.2 参数配置
方式一:yaml配置
resilience4j:
circuitbreaker:
instances:
conditionalServiceBreaker: # 与代码中CIRCUIT_BREAKER_NAME一致
failure-rate-threshold: 50 # 失败率阈值(%)
wait-duration-in-open-state: 10s # OPEN状态持续时间
permitted-number-of-calls-in-half-open-state: 3
sliding-window-size: 10 # 滑动窗口请求数
sliding-window-type: COUNT_BASED # COUNT_BASED/COUNT_BASED
automatic-transition-from-open-to-half-open-enabled: true
timelimiter:
instances:
conditionalServiceBreaker:
timeout-duration: 3s # 超时时间
方式二:
使用配置类
@Configuration
public class CustomizeCircuitBreakerConfig {
@Bean
public ReactiveResilience4JCircuitBreakerFactory defaultCustomizer() {
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom() //
.slidingWindowType(CircuitBreakerConfig.SlidingWindowType.TIME_BASED) // 滑动窗口的类型为时间窗口
.slidingWindowSize(10) // 时间窗口的大小为60秒
.minimumNumberOfCalls(5) // 在单位时间窗口内最少需要5次调用才能开始进行统计计算
.failureRateThreshold(50) // 在单位时间窗口内调用失败率达到50%后会启动断路器
.enableAutomaticTransitionFromOpenToHalfOpen() // 允许断路器自动由打开状态转换为半开状态
.permittedNumberOfCallsInHalfOpenState(5) // 在半开状态下允许进行正常调用的次数
.waitDurationInOpenState(Duration.ofSeconds(5)) // 断路器打开状态转换为半开状态需要等待60秒
.recordExceptions(Throwable.class) // 所有异常都当作失败来处理
.build();
ReactiveResilience4JCircuitBreakerFactory factory = new ReactiveResilience4JCircuitBreakerFactory();
factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(200)).build())
.circuitBreakerConfig(circuitBreakerConfig).build());
return factory;
}
}
2.3 断路器过滤器
动态判断请求特征并条件化应用断路器。
@Component
@Order(-100) // 高优先级,确保在路由过滤器前执行
public class ConditionalCircuitBreakerFilter implements GlobalFilter {
private final ReactiveCircuitBreakerFactory circuitBreakerFactory;
private static final String CIRCUIT_BREAKER_NAME = "conditionalServiceBreaker";
private static final String TRIGGER_HEADER = "X-Enable-CircuitBreaker"; // 可替换为其他attribute判断逻辑
public ConditionalCircuitBreakerFilter(ReactiveCircuitBreakerFactory circuitBreakerFactory) {
this.circuitBreakerFactory = circuitBreakerFactory;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// === 条件判断逻辑(可根据需求扩展)===
boolean shouldApplyCircuitBreaker = shouldApplyBreaker(exchange);
if (shouldApplyCircuitBreaker) {
ReactiveCircuitBreaker circuitBreaker = circuitBreakerFactory.create(CIRCUIT_BREAKER_NAME);
return circuitBreaker.run(
// 包装整个后续过滤器链(含路由、负载均衡、下游调用)
chain.filter(exchange).then(Mono.empty()),
// Fallback逻辑:断路器打开或调用失败时执行
throwable -> handleFallback(exchange, throwable)
).then();
}
// 不满足条件:直接放行,不经过断路器
return chain.filter(exchange);
}
/**
* 条件判断扩展点(按需修改)
*/
private boolean shouldApplyBreaker(ServerWebExchange exchange) {
// 方案1:检查请求头
String headerVal = exchange.getRequest().getHeaders().getFirst(TRIGGER_HEADER);
if ("true".equalsIgnoreCase(headerVal)) return true;
// 方案2:检查请求参数(示例)
// String param = exchange.getRequest().getQueryParams().getFirst("use_circuit");
// if ("1".equals(param)) return true;
// 方案3:检查自定义attribute(需前置过滤器设置)
// Boolean attr = exchange.getAttribute("custom.circuit.trigger");
// return attr != null && attr;
return false;
}
/**
* Fallback处理(可扩展为转发到/fallback路径)
*/
private Mono<Void> handleFallback(ServerWebExchange exchange, Throwable throwable) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
String body = String.format(
"{\"error\":\"CIRCUIT_BREAKER_OPEN\",\"message\":\"Service protected by circuit breaker\",\"trigger\":\"%s\"}",
TRIGGER_HEADER
);
DataBuffer buffer = response.bufferFactory()
.wrap(body.getBytes(StandardCharsets.UTF_8));
return response.writeWith(Mono.just(buffer));
}
}
更多推荐




所有评论(0)