/** * 断路器模式实现 * 防止系统雪崩效应,保护系统稳定性 */ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; public class CircuitBreaker { // 断路器状态枚举 public enum State { CLOSED, // 关闭状态,允许请求通过 OPEN, // 开路状态,拒绝请求 HALF_OPEN // 半开状态,允许有限请求通过以检测服务是否恢复 } private final String name; // 断路器名称 private final int failureThreshold; // 失败阈值 private final long resetTimeoutMs; // 重置超时时间(毫秒) private final int successThreshold; // 半开状态下的成功阈值 private volatile State state = State.CLOSED; // 当前状态 private final AtomicInteger failureCount = new AtomicInteger(0); // 失败计数 private final AtomicInteger successCount = new AtomicInteger(0); // 成功计数 private final AtomicLong lastFailureTime = new AtomicLong(0); // 最后一次失败时间 // 默认构造函数 public CircuitBreaker(String name) { this(name, 5, 30000, 2); // 默认5次失败后开路,30秒后尝试半开,2次成功后关闭 } // 自定义参数构造函数 public CircuitBreaker(String name, int failureThreshold, long resetTimeoutMs, int successThreshold) { this.name = name; this.failureThreshold = failureThreshold; this.resetTimeoutMs = resetTimeoutMs; this.successThreshold = successThreshold; System.out.println("断路器初始化: " + name + ", 失败阈值: " + failureThreshold + ", 重置时间: " + resetTimeoutMs + "ms"); } // 尝试执行请求 public boolean allowRequest() { switch (state) { case CLOSED: // 关闭状态,允许请求通过 return true; case OPEN: // 开路状态,检查是否可以进入半开状态 if (System.currentTimeMillis() - lastFailureTime.get() > resetTimeoutMs) { // 超时,切换到半开状态 state = State.HALF_OPEN; System.out.println("断路器状态切换: " + name + " 从 OPEN 到 HALF_OPEN"); return true; } return false; case HALF_OPEN: // 半开状态,允许请求通过 return true; default: return false; } } // 记录请求成功 public void recordSuccess() { switch (state) { case CLOSED: // 关闭状态,重置失败计数 failureCount.set(0); break; case HALF_OPEN: // 半开状态,增加成功计数 int currentSuccess = successCount.incrementAndGet(); if (currentSuccess >= successThreshold) { // 达到成功阈值,切换到关闭状态 reset(); System.out.println("断路器状态切换: " + name + " 从 HALF_OPEN 到 CLOSED"); } break; } } // 记录请求失败 public void recordFailure() { switch (state) { case CLOSED: // 关闭状态,增加失败计数 int currentFailure = failureCount.incrementAndGet(); if (currentFailure >= failureThreshold) { // 达到失败阈值,切换到开路状态 state = State.OPEN; lastFailureTime.set(System.currentTimeMillis()); System.out.println("断路器状态切换: " + name + " 从 CLOSED 到 OPEN"); } break; case HALF_OPEN: // 半开状态下失败,立即切换到开路状态 state = State.OPEN; lastFailureTime.set(System.currentTimeMillis()); successCount.set(0); System.out.println("断路器状态切换: " + name + " 从 HALF_OPEN 到 OPEN"); break; } } // 重置断路器 public void reset() { state = State.CLOSED; failureCount.set(0); successCount.set(0); lastFailureTime.set(0); System.out.println("断路器重置: " + name); } // 获取当前状态 public State getState() { return state; } // 获取名称 public String getName() { return name; } // 获取失败计数 public int getFailureCount() { return failureCount.get(); } @Override public String toString() { return "CircuitBreaker[name=" + name + ", state=" + state + ", failures=" + failureCount.get() + "]"; } }