固定窗口算法

实现思路:

  1. 把时间线划分为多个独立且固定大小的窗口
  2. 设置一个计数器,用于记录限流阈值
  3. 拦截所有请求执行canPass操作,如果在当前数据窗口计数器超过了阈值,则后续落在该窗口的请求都会被拒绝,没有超过则计数器 +1
  4. 时间到达下一个时间窗口后,重置时间窗口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class CounterRateLimit implements RateLimit,Runnable {

//通过阈值
private Integer limitCount = 10;

//通过当前请求书
private AtomicInteger passCount;

//统计时间间隔 100ms
private long period = 100;

//窗口的单位MILLISECONDS 毫秒
private TimeUnit timeUnit;

private ScheduledExecutorService scheduledExecutorService;

public CounterRateLimit(Integer limitCount, long period, TimeUnit timeUnit){
this.limitCount = limitCount;
this.period = period;
this.timeUnit = timeUnit;
this.passCount = new AtomicInteger(1);
this.startResetTask();
}

public boolean canPass() throws BlockException {
if(passCount.incrementAndGet() > limitCount){
throw new BlockException();
}
return true;
}

@Override
public void run() {
passCount.set(0);
}

private void startResetTask(){
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(this, 0, period, TimeUnit.MILLISECONDS);
}

public static void main(String[] args) throws BlockException {
CounterRateLimit counterRateLimit = new CounterRateLimit(10, 1000, TimeUnit.MILLISECONDS);
for (int i = 0; i < 10000; i++){
if(counterRateLimit.canPass()){
System.out.println("通过第【" + i + "】个请求");
Thread.sleep(10);
}
}
}
}

固定窗口算法
http://www.zivjie.cn/2023/12/09/算法/限流算法/固定窗口算法/
作者
Francis
发布于
2023年12月9日
许可协议