计数器限流工具类

98 阅读1分钟

计数器算法是在一定的时间间隔里,记录请求次数,当请求次数超过该时间限制时,就把计数器清零,然后重新计算。当请求次数超过间隔内的最大次数时,拒绝访问。

`import java.util.concurrent.atomic.AtomicLong;

/**

  • 计数器限流
    */
    public class CountRateLimiter {
    private AtomicLong counter = new AtomicLong(0);
    private long timestamp = System.currentTimeMillis();
    private long permitsPerSecond;
    private static long MS = 1000;

public CountRateLimiter(long permitsPerSecond) {
this.permitsPerSecond = permitsPerSecond;
}

public boolean tryAcquire() {
long now = System.currentTimeMillis();
if (now - timestamp < MS) {
if (counter.get() < permitsPerSecond) {
counter.incrementAndGet();
return true;
} else {
return false;
}
}
return false;

}

}`

`package com.yonyou.iuap.dispatch.util;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import java.util.concurrent.TimeUnit;

/**

  • 计数器限流工具类

*/
public class CountRateLimiterUtils {

final static Cache<String, CountRateLimiter> COUNT_RATE_LIMITER_CACHE = CacheBuilder.newBuilder().expireAfterWrite(2000, TimeUnit.MILLISECONDS).build();

private static final Object lock = new Object();

private static CountRateLimiter getCountRateLimter(String code, long permitsPerSecond) {
CountRateLimiter object = COUNT_RATE_LIMITER_CACHE.getIfPresent(code);
if (object == null) {
synchronized (lock) {
object = COUNT_RATE_LIMITER_CACHE.getIfPresent(code);
if (object == null) {
object = new CountRateLimiter(permitsPerSecond);
COUNT_RATE_LIMITER_CACHE.put(code, object);
}
}
}
return object;
}

public static boolean tryAcquire(String code, long permitsPerSecond) {
code = code + DateUtil.current() / 1000;
CountRateLimiter countRateLimiter = getCountRateLimter(code, permitsPerSecond);
return countRateLimiter.tryAcquire();
}

}`