Resilience4j RateLimiter源码解读

本文详细解析了RateLimiter的限流原理及其实现机制,包括如何通过装饰器模式应用限流,以及核心方法waitForPermission的具体流程。探讨了从配置文件中读取超时时间,并调用getPermission方法的全过程。
摘要由CSDN通过智能技术生成

RateLimiter运作原理
我们使用RateLimiter装饰我们的方法时,其实现其实只是调用了RateLimiter的waitForPermission方法。

    static default <T> CheckedFunction0<T> decorateCheckedSupplier(RateLimiter rateLimiter, CheckedFunction0<T> supplier) {
        return () -> {
            waitForPermission(rateLimiter);
            return supplier.apply();
        };
    }

    static default CheckedRunnable decorateCheckedRunnable(RateLimiter rateLimiter, CheckedRunnable runnable) {
        return () -> {
            waitForPermission(rateLimiter);
            runnable.run();
        };
    }

    static default <T, R> CheckedFunction1<T, R> decorateCheckedFunction(RateLimiter rateLimiter, CheckedFunction1<T, R> function) {
        return (t) -> {
            waitForPermission(rateLimiter);
            return function.apply(t);
        };
    }

来看waitForPermission的实现,其核心是从配置文件中获取等待权限的超时时间(配置中timeoutInMillis)并调用rateLimiter.getPermission方法:

    static default void waitForPermission(RateLimiter rateLimiter) throws IllegalStateException, RequestNotPermitted {
        RateLimiterConfig rateLimiterConfig = rateLimiter.getRateLimiterConfig();
        Duration timeoutDuration = rateLimiterConfig.getTimeoutDuration();	//从配置中读取timeoutDuration
        boolean permission = rateLimiter.getPermission(timeoutDuration);	//调用该方法来尝试获取调用权限
        if(Thread.interrupted()) {
            throw new IllegalStateException("Thread was interrupted during permission wait");
        } else if(!permission) {
            throw new RequestNotPermitted("Request not permitted for limiter: " + rateLimiter.getName());
        }
    }

rateLimiter.getPermission方法的实现是RateLimiter的核心,默认实现类为AtomicRateLimiter(令牌桶限流)。

  public boolean getPermission(Duration timeoutDuration) {
        long timeoutInNanos = timeoutDuration.toNanos(); //获取超时时间的纳秒数
        AtomicRateLimiter.State modifiedState = this.updateStateWithBackOff(timeoutInNanos); //获取下一个状态
        boolean result = this.waitForPermissionIfNecessary(timeoutInNanos, modifiedState.nanosToWait);	//如果能获取执行次数则返回true,反之返回false
        this.publishRateLimiterEvent(result);	//成功获取permission发布RateLimiterOnSuccessEvent,反之发布RateLimiterOnFailureEvent
        return result;
    }

updateStateWithBackOff方法主要比对了当前State和下一个State是否相等,如相等返回当前State,反之返回下一个State。

   private AtomicRateLimiter.State updateStateWithBackOff(long timeoutInNanos) {
        AtomicRateLimiter.State prev;
        AtomicRateLimiter.State next;
        do {
            prev = (AtomicRateLimiter.State)this.state.get();
            next = this.calculateNextState(timeoutInNanos, prev);
        } while(!this.compareAndSet(prev, next));

        return next;
    }

计算下一个State相关信息,如permissions,nanosToWait,cycle值并封装成新State返回。

    private AtomicRateLimiter.State calculateNextState(long timeoutInNanos, AtomicRateLimiter.State activeState) {
        long cyclePeriodInNanos = activeState.config.getLimitRefreshPeriodInNanos(); //每个时间段对应纳秒数,由配置文件中的limitRefreshPeriodInMillis计算而来
        int permissionsPerCycle = activeState.config.getLimitForPeriod(); //每个时间段内可执行次数,对应配置文件中的limitForPeriod
        long currentNanos = this.currentNanoTime();  //计算从本类初始化到现在的纳秒数
        long currentCycle = currentNanos / cyclePeriodInNanos;	//计算当前cycle数 
        long nextCycle = activeState.activeCycle;
        int nextPermissions = activeState.activePermissions;
        long nextNanosToWait;
        //如果已经进入后续的cycle,则重新计算nextPermissions值,也就是获取真正当前剩余调用次数availablePermissions
        if(nextCycle != currentCycle) {
            nextNanosToWait = currentCycle - nextCycle;
            long nextState = nextNanosToWait * (long)permissionsPerCycle;
            nextCycle = currentCycle;
            nextPermissions = (int)Long.min((long)nextPermissions + nextState, (long)permissionsPerCycle);
        }

        nextNanosToWait = this.nanosToWaitForPermission(cyclePeriodInNanos, permissionsPerCycle, nextPermissions, currentNanos, currentCycle);	//计算所需等待时间
        AtomicRateLimiter.State nextState1 = this.reservePermissions(activeState.config, timeoutInNanos, nextCycle, nextPermissions, nextNanosToWait);	//所需时间和超时时间做对比,判断能否在能及时执行完,如能则减少可用次数permission-1
        return nextState1;
    }

nanosToWaitForPermission的实现,逻辑为判断是否还有可用执行次数,如果还有次数则返回0L,否则计算总共需要等待的时间,如果waitInterval设置的长,可能会导致欠了很多次,需要多个cycle才能执行完

    private long nanosToWaitForPermission(long cyclePeriodInNanos, int permissionsPerCycle, int availablePermissions, long currentNanos, long currentCycle) {
        if(availablePermissions > 0) {
            return 0L;
        } else {
            long nextCycleTimeInNanos = (currentCycle + 1L) * cyclePeriodInNanos;
            long nanosToNextCycle = nextCycleTimeInNanos - currentNanos;
            int fullCyclesToWait = -availablePermissions / permissionsPerCycle;
            return (long)fullCyclesToWait * cyclePeriodInNanos + nanosToNextCycle;
        }
    }

reservePermissions实现,将所需时间和超时时间做对比,判断能否在能及时执行完,如能则消费一次可用次数permission-1,同时更新cycle、nanosToWait。

    private AtomicRateLimiter.State reservePermissions(RateLimiterConfig config, long timeoutInNanos, long cycle, int permissions, long nanosToWait) {
        boolean canAcquireInTime = timeoutInNanos >= nanosToWait;
        int permissionsWithReservation = permissions;
        if(canAcquireInTime) {
            permissionsWithReservation = permissions - 1;
        }

        return new AtomicRateLimiter.State(config, cycle, permissionsWithReservation, nanosToWait, null);
    }

更新完整体状态后就可以进行acquire操作了,成功acquire则返回true,反之返回false。

    private boolean waitForPermissionIfNecessary(long timeoutInNanos, long nanosToWait) {
        boolean canAcquireImmediately = nanosToWait <= 0L;
        boolean canAcquireInTime = timeoutInNanos >= nanosToWait;
        if(canAcquireImmediately) {	//等待nanosToWait时间为0,立即获取返回true
            return true;
        } else if(canAcquireInTime) {	//如能及时获取则尝试阻塞线程(park)后判断线程是否被中断,如未中断则成功,反之为失败
            return this.waitForPermission(nanosToWait);
        } else {	//不能及时获取则等待设置的超时时间后返回false
            this.waitForPermission(timeoutInNanos);
            return false;
        }
    }

限流器的状态AtomicRateLimiter.State

private static class State {
        private final RateLimiterConfig config;	//存储了我们的限流器配置
        private final long activeCycle;	//当前cycle
        private final int activePermissions;	//该cycle下剩余可放行请求次数
        private final long nanosToWait;	//剩余等待纳秒数

        private State(RateLimiterConfig config, long activeCycle, int activePermissions, long nanosToWait) {
            this.config = config;
            this.activeCycle = activeCycle;
            this.activePermissions = activePermissions;
            this.nanosToWait = nanosToWait;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值