您的位置:首页 > 健康 > 美食 > 限流算法整理——滑动窗口限流算法

限流算法整理——滑动窗口限流算法

2025/1/5 23:29:52 来源:https://blog.csdn.net/Wang_Zimeng/article/details/139388930  浏览:    关键词:限流算法整理——滑动窗口限流算法

限流算法描述

滑动窗口限流需要将每个窗口空间划分为无限小的窗口区间,并且动态调整区间的起始点,并且在调整完毕之后需要判断各个区间,累加各个区间的请求,查看是否到达最大的阈值,以此返回允许请求还是拒绝请求

算法实现

结构定义

首先需要定义结构,因为在滑动窗口中,起到限流作用的应该是最大请求数和当前的小时间窗口(单位: 时间/ 毫秒),一开始的窗口起点应该是最新的当前系统时间

 private long windowStart = System.currentTimeMillis();
//滑动窗口的单位(小)窗口长度private long windowSize;
//限流最大的请求数量private int maxRequest;
private Map<Long, LongAdder> windowCount = new ConcurrentHashMap<>();

限流分析

首先进入tryAcquire方法中需要判断最新的时间是否已经走过了窗口的右侧,如果是,更新窗口,并且清空窗口内的请求

 long currentTimeMillis = System.currentTimeMillis();long windowEnd = windowStart + windowSize;if (windowEnd < System.currentTimeMillis()) {//重新计数windowStart = System.currentTimeMillis();windowCount.clear();}

之后,进入到窗口中请求的计算,需要对更新过后的时间窗口区间进行request的统计,为了保证多线程情况下的并发安全问题,这里是哟inglongAdder作为计数器,并且对方法进行synchronized关键字修饰

		long windowId = currentTimeMillis - (currentTimeMillis % windowSize);LongAdder count = windowCount.computeIfAbsent(windowId, k -> new LongAdder());// 尝试增加计数count.increment();// 检查是否超过限制return count.longValue() <= maxRequest;

注意这部分的关键就是计算窗口标识的部分,我们用当前时间 - 当前时间对于时间窗口的取模,来判断属于哪个编号的窗口,举例说明:

-假设窗口大小是1000毫秒(即1秒),当前时间是12345ms。currentTimeMillis % windowSizeInMs 计算 12345 % 1000,结果是 45。 然后我们从这个当前时间中减去余数 12345 - 45,得到 12300,因此这个时间的请求属于 12300这个时间窗口

我们最终在mian函数中执行初始化和测试用例,给出限制请求大小为2,时间窗口为1s即1000ms,在for循环中模拟 10次请求

public static void main(String[] args) {SlidingWindowDemo rateLimiter = new SlidingWindowDemo(2, 1000); // 窗口容量为10,窗口大小为1秒// 模拟请求for (int i = 0; i < 10; i++) {// 模拟请求之间的时间间隔try {TimeUnit.MILLISECONDS.sleep(200); // 每个请求间隔200毫秒} catch (InterruptedException e) {e.printStackTrace();}// 尝试获取限流器boolean acquired = rateLimiter.tryAcquire();System.out.println("Request " + (i + 1) + ": " + (acquired ? "Acquired" : "Denied"));}}

最终运行结果

收到拒绝消息,说明限流算法成功
请添加图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com