我们使用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;
}
}