一、限流器
public class RateLimiter { private static final int WINDOW_LIMIT = 100; private static long WINDOW_START_TIME = System.currentTimeMillis(); private static final long WINDOW_DURATION = 60 * 1000; private static final AtomicInteger WINDOW_ACC_CNT = new AtomicInteger(0); public boolean tryAcquire() { long now = System.currentTimeMillis(); if (now - WINDOW_START_TIME >= WINDOW_DURATION) { WINDOW_START_TIME = now; WINDOW_ACC_CNT.set(0); } return WINDOW_ACC_CNT.incrementAndGet() <= WINDOW_LIMIT; } public void acquire(){ for(;;){ try { if (tryAcquire()){ break; } TimeUnit.MICROSECONDS.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } } }
二、熔断器
public class CircuitBreaker { /** * 失败窗口统计开始时间 */ private Long failWindowStartTime = System.currentTimeMillis(); /** * 失败窗口,默认60s */ private Long failWindowDuration = 60000L; /** * 窗口内累积失败次数,默认100次 */ private AtomicInteger failWindowAccFailCount = new AtomicInteger(0); /** * 窗口内最大失败次数 */ private Long failWindowMaxCount = 5L; /** * 熔断器开始时间 */ private Long breakerStartTime; /** * 熔断两分钟 */ private Long breakerDuration = 2 * 60000L; /** * 熔断器状态 */ private State state = State.CLOSED; public static CircuitBreaker create(MiddlewareConfigProperties.LimitMiddlewareConfig limitConfig) { CircuitBreaker circuitBreaker = new CircuitBreaker(); if (limitConfig == null){ return circuitBreaker; } if (limitConfig.getFailWindowDuration() != null) { circuitBreaker.setFailWindowDuration(limitConfig.getFailWindowDuration()); } if (limitConfig.getFailWindowMaxCount() != null) { circuitBreaker.setFailWindowMaxCount(limitConfig.getFailWindowMaxCount()); } if (limitConfig.getBreakerDuration() != null) { circuitBreaker.setBreakerDuration(limitConfig.getBreakerDuration()); } return circuitBreaker; } public enum State { CLOSED, OPEN } public void onSuccess() { // reset reset(); } public void reset() { state = State.CLOSED; failWindowStartTime = System.currentTimeMillis(); failWindowAccFailCount.set(0); } public void onFail() { long duration = System.currentTimeMillis() - failWindowStartTime; if (duration >= failWindowDuration) { // 如果已超过窗口时间,重置 reset(); } // 判断失败次数 int failCnt = failWindowAccFailCount.incrementAndGet(); if (failCnt >= failWindowMaxCount) { // 打开熔断器 state = State.OPEN; breakerStartTime = System.currentTimeMillis(); } } public State getBreakerState() { if (state == State.CLOSED) { return State.CLOSED; } // 判断是否已经超过熔断时间 long breakDuration = System.currentTimeMillis() - breakerStartTime; if (breakDuration > breakerDuration) { // 已经熔断2分钟,关闭熔断器 reset(); return State.CLOSED; } return State.OPEN; } }
还没有评论,来说两句吧...