计数器法是限流算法里最简单也是最容易实现的一种算法。
比如:对于一个接口来说,我们1分钟的访问次数不能超过100个。那么我们可以这么做:在一开始的时候,我们可以设置一个counter(计数器),每当一个请求过来的时候,counter就加1,如果counter的值大于100并且该请求与第一个 请求的间隔时间还在1分钟之内,那么说明请求数过多;如果该请求与第一个请求的间隔时间大于1分钟,且counter的值还在限流范围内,那么就重置 counter。
代码如下(示例):
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author yang
* @date 2024/1/10 15:53
*/
public class RateLimiter {
/**
* 最大请求数
*/
private static final int MAX_REQUESTS = 100;
/**
* 时间窗口大小,1秒
*/
private static final long INTERVAL_MILLIS = 1000;
private final AtomicInteger count = new AtomicInteger(0);
private long windowStart = System.currentTimeMillis();
public boolean allowRequest() {
long now = System.currentTimeMillis();
if (now - windowStart > INTERVAL_MILLIS) {
// 如果超过了时间窗口,则重置计数器和时间窗口起始时间
count.set(1);
windowStart = now;
return true;
} else {
if (count.get() < MAX_REQUESTS) {
// 如果未超过最大请求数,则允许该请求,并增加计数器
count.incrementAndGet();
return true;
} else {
// 否则拒绝该请求
return false;
}
}
}
public static void main(String[] args) {
RateLimiter limiter = new RateLimiter();
for (int i = 0; i < 110; i++) {
if (limiter.allowRequest()) {
System.out.println("允许请求");
} else {
System.out.println("限流");
}
}
}
}