package com.xxxx.seckill.limit;
import java.util.LinkedList;
/**
* @author WangHeng
* @version V1.0
* @date 2023/1/9- 16:15
* @desc 滑动时间限流算法
**/
public class AutoTimeLimit {
//单位时间内请求的总个数
private Integer reqCount;
//使用LinkedList记录10个格子
private LinkedList<Integer> slots = new LinkedList<>();
//单位时间内最大请求数
private Integer limitNum = 100;
//滑动时间窗口中每个格子的时间长度 单位:ms
private Long windowLength = 100L;
//滑动时间窗口中的格子数量
private Integer windowNum = 10;
//定义构造方法,开辟新的线程,每100ms添加一个新的格子
// ,如果大于10个的话就移除并更新全局变量的个数。
public AutoTimeLimit() {
//初始化的时候add一个0至list当中
slots.addLast(0);
new Thread(() -> {
try {
//然后每个100ms,在list后面add一个0
Thread.sleep(windowLength);
} catch (InterruptedException e) {
e.printStackTrace();
}
slots.addLast(0);
//如果list的size一旦大于10,将第一个元素remove掉,使得list的size永远等于10
if (slots.size() > windowNum) {
//倘若size大于10的时候,时间肯定是超过了1s中了,
// 所以第一个元素已经不在统计单位时间内了,应删掉第一个格子的数目,更新全局的个数。
reqCount = reqCount - slots.peekFirst();
//移除第一个格子的元素
slots.removeFirst();
}
}).start();
}
/**
* 方法限流方法
*
* @return true:代表限流 false:代表通过
*/
public synchronized Boolean limit() {
//如果全局变量的个数加上当前访问的个数1大于100的话,直接限流.
if ((reqCount + 1) > limitNum) {
return true;
}
//slots.size()-1为最后一个格子的下标,使得最后一个格子的数目+1
slots.set(slots.size() - 1, slots.peekLast() + 1);
//全局变量更新个数
reqCount++;
//表示通过
return false;
}
}
滑动时间窗口限流算法实现
最新推荐文章于 2024-07-13 17:23:56 发布