Java熔断器模式详解
Java熔断器模式详解
什么是熔断器
熔断器(Circuit Breaker)是一种保护机制,当下游服务出现问题时,快速失败并返回降级响应,避免级联故障。
熔断器状态
关闭(CLOSED) ──失败率超阈值──→ 打开(OPEN)
↓ 等待超时
半开(HALF_OPEN)
↓ ↓
成功→CLOSED 失败→OPEN
public class CircuitBreakerDemo {
private enum State { CLOSED, OPEN, HALF_OPEN }
private State state = State.CLOSED;
private int failureCount = 0;
private int successCount = 0;
private final int failureThreshold = 5;
private final long openTimeout = 5000;
private long lastFailureTime = 0;
public String call() {
if (state == State.OPEN) {
if (System.currentTimeMillis() - lastFailureTime > openTimeout) {
state = State.HALF_OPEN;
} else {
throw new RuntimeException("熔断器打开,快速失败");
}
}
try {
String result = doCall();
onSuccess();
return result;
} catch (Exception e) {
onFailure();
throw e;
}
}
private void onSuccess() {
if (state == State.HALF_OPEN) {
state = State.CLOSED;
}
failureCount = 0;
successCount++;
}
private void onFailure() {
failureCount++;
lastFailureTime = System.currentTimeMillis();
if (failureCount >= failureThreshold) {
state = State.OPEN;
}
}
}
Resilience4j
依赖配置
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.1.0</version>
</dependency>
基本配置
resilience4j:
circuitbreaker:
instances:
userService:
slidingWindowSize: 10
failureRateThreshold: 50
waitDurationInOpenState: 10s
permittedNumberOfCallsInHalfOpenState: 3
slidingWindowType: TIME_BASED
minimumNumberOfCalls: 5
retry:
instances:
userService:
maxAttempts: 3
waitDuration: 500ms
enableExponentialBackoff: true
exponentialBackoffMultiplier: 2
retryExceptions:
- java.io.IOException
- java.util.concurrent.TimeoutException
ratelimiter:
instances:
userService:
limitForPeriod: 10
limitRefreshPeriod: 1s
timeoutDuration: 0
timelimiter:
instances:
userService:
timeoutDuration: 3s
注解使用
@Service
public class UserServiceWithResilience4j {
@CircuitBreaker(name = "userService", fallbackMethod = "getUserFallback")
public User getUser(Long id) {
return restTemplate.getForObject(
"http://user-service/api/users/" + id, User.class);
}
public User getUserFallback(Long id, Exception e) {
log.warn("获取用户失败,使用降级数据: {}", e.getMessage());
return new User(id, "默认用户", "降级数据");
}
@Retry(name = "userService", fallbackMethod = "retryFallback")
public String fetchData(String url) {
return restTemplate.getForObject(url, String.class);
}
public String retryFallback(String url, Exception e) {
return "降级数据";
}
@RateLimiter(name = "userService")
public void rateLimitedOperation() {
System.out.println("限流保护的操作");
}
@TimeLimiter(name = "userService")
public CompletableFuture<User> timeoutOperation(Long id) {
return CompletableFuture.supplyAsync(() ->
restTemplate.getForObject(
"http://user-service/api/users/" + id, User.class)
);
}
}
组合使用
@Service
public class CompositeResilience {
// 熔断 + 重试 + 限流 + 超时
@CircuitBreaker(name = "userService", fallbackMethod = "fallback")
@Retry(name = "userService")
@RateLimiter(name = "userService")
@TimeLimiter(name = "userService")
public CompletableFuture<User> getUser(Long id) {
return CompletableFuture.supplyAsync(() ->
restTemplate.getForObject(
"http://user-service/api/users/" + id, User.class)
);
}
public CompletableFuture<User> fallback(Long id, Exception e) {
return CompletableFuture.completedFuture(
new User(id, "默认用户", "降级数据")
);
}
}
事件监听
@Component
public class CircuitBreakerEventListener {
@EventListener
public void onCircuitBreakerEvent(CircuitBreakerOnStateChangeEvent event) {
log.info("熔断器状态变更: {} -> {}",
event.getStateTransition().getFromState(),
event.getStateTransition().getToState());
}
@EventListener
public void onCircuitBreakerError(CircuitBreakerOnErrorEvent event) {
log.warn("熔断器错误: {}", event.getThrowable().getMessage());
}
@EventListener
public void onCircuitBreakerSuccess(CircuitBreakerOnSuccessEvent event) {
log.info("熔断器调用成功");
}
}
降级策略
@Component
public class FallbackStrategy {
// 缓存降级
public User getUserWithCache(Long id) {
try {
User user = callRemoteService(id);
cache.put(id, user);
return user;
} catch (Exception e) {
User cached = cache.get(id);
if (cached != null) {
return cached;
}
return getDefaultUser(id);
}
}
// 默认值降级
public User getDefaultUser(Long id) {
User user = new User();
user.setId(id);
user.setName("默认用户");
user.setStatus("服务暂时不可用");
return user;
}
// 兜底接口降级
public User getUserFromFallbackService(Long id) {
try {
return fallbackService.getUser(id);
} catch (Exception e) {
return getDefaultUser(id);
}
}
}
监控面板
@Configuration
public class Resilience4jActuatorConfig {
@Bean
public HealthIndicator circuitBreakerHealthIndicator(
CircuitBreakerRegistry registry) {
return new CircuitBreakerHealthIndicator(registry);
}
}
// 访问 /actuator/health 查看健康状态
// 访问 /actuator/circuitbreakers 查看所有熔断器状态
最佳实践
// 1. 合理设置阈值
// 关键服务:failureRateThreshold=50, slidingWindowSize=10
// 非关键服务:failureRateThreshold=30, slidingWindowSize=5
// 2. 降级策略要具体
// 数据查询:返回缓存数据
// 操作类:返回操作失败提示
// 通知类:异步重试
// 3. 监控告警
@Component
public class CircuitBreakerAlert {
@EventListener
public void onStateChange(CircuitBreakerOnStateChangeEvent event) {
if (event.getStateTransition().getToState() == State.OPEN) {
alertService.sendAlert(
"熔断器打开: " + event.getName());
}
}
}
总结
熔断器是微服务架构中保护系统稳定性的重要组件。Resilience4j提供了熔断、重试、限流、超时等完整的弹性能力。合理配置阈值和降级策略,可以有效防止级联故障。