限流器 和 熔断器实现

限流器 和 熔断器实现

码农世界 2024-06-04 前端 93 次浏览 0个评论

一、限流器

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;
    }
}

转载请注明来自码农世界,本文标题:《限流器 和 熔断器实现》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,93人围观)参与讨论

还没有评论,来说两句吧...

Top