滑动窗口限流

滑动窗口限流是一种常用的限流算法,通过维护一个固定大小的窗口,在单位时间内允许通过的请求次数不超过设定的阈值。具体来说,滑动窗口限流算法通常包括以下几个步骤:

  1. 初始化:设置窗口大小、请求次数阈值和时间间隔。
  2. 维护窗口:将请求按照时间顺序放入窗口中,并保持窗口内请求数量不超过阈值。
  3. 检查通过:每当有新的请求到达时,检查窗口内请求的总数是否超过阈值,如果未超过则允许通过,同时移除窗口最老的请求。
  4. 更新窗口:随着时间的推移,更新窗口内的请求情况,确保窗口内的请求符合限流条件。

滑动窗口限流算法可以有效控制系统的请求流量,避免系统被大量请求压垮。同时,由于其简单高效的特点,被广泛应用于接口限流、流量控制等场景中。需要注意的是,滑动窗口限流算法对于突发请求并不能完全解决问题,因此在实际应用中可能需要结合其他策略进行综合考虑。

基于redis-zset实现的滑动窗口算法流程

核心代码

/**
* 滑动窗口限流. 需要注意的是,我们要定期清楚过期的key,否则会导致内存泄漏,可以使用ZREMRANGEBYSCORE方法实现.
* @param key 限流的key
* @param timeWindow 单位时间,秒
* @param limit 窗口大小,单位时间最大容许的令牌数
* @param runnable 成功后的回调方法
*/
public void slidingWindow(String key, int timeWindow, int limit, Runnable runnable) {
Long currentTime = System.currentTimeMillis();
if (redisTemplate.hasKey(key)) {
Long intervalTime = timeWindow * 1000L;
Long from = currentTime - intervalTime;
Integer count = redisTemplate.opsForZSet().rangeByScore(key, from, currentTime).size();
if (count != null && count >= limit) {
throw new RedisLimitException("每" + timeWindow + "秒最多只能访问" + limit + "次.");
}
log.info("from key:{}~{},current count:{}", from, currentTime, count);
}
redisTemplate.opsForZSet().add(key, UUID.randomUUID().toString(), currentTime);
Optional.ofNullable(runnable).ifPresent(o -> o.run());
}

上面实现了一个基于时间戳为主要窗口依据的滑动窗口限流逻辑,由于zset的数据量会随着时间的流失而变大,所以我们需要定期再根据score来清理它。

/**
* 清期昨天的zset元素,这块应该写个任务调度,每天执行一次,清量需要的zset元素.
* @param key
*/
public void delByYesterday(String key) {
Instant currentInstant = Instant.now();
Instant oneDayAgoInstant = currentInstant.minusSeconds(86400);
long oneDayAgoTimeMillis = oneDayAgoInstant.toEpochMilli();
redisTemplate.opsForZSet().removeRangeByScore(key, 0, oneDayAgoTimeMillis); }

上面代码逻辑,事实上,我们可以通过其它语言去实现,比较通过go可以实现相关的逻辑,从新可以在MSE网关上实现限流功能。

算法~利用zset实现滑动窗口限流的更多相关文章

  1. ASP.NET Core中使用滑动窗口限流

    滑动窗口算法用于应对请求在时间周期中分布不均匀的情况,能够更精确的应对流量变化,比较著名的应用场景就是TCP协议的流量控制,不过今天要说的是服务限流场景中的应用. 算法原理 这里假设业务需要每秒钟限流 ...

  2. Redis的自增也能实现滑动窗口限流?

    限流是大家开发之路上一定会遇到的需求.比如:限制一定时间内,接口请求请求频率:一定时间内用户发言.评论次数等等,类似于滑动窗口算法.这里分享一份拿来即用的代码,一起看看如何利用常见的 Redis 实现 ...

  3. ASP.NET Core中使用固定窗口限流

    算法原理 固定窗口算法又称计数器算法,是一种简单的限流算法.在单位时间内设定一个阈值和一个计数值,每收到一个请求则计数值加一,如果计数值超过阈值则触发限流,如果达不到则请求正常处理,进入下一个单位时间 ...

  4. 算法与数据结构基础 - 滑动窗口(Sliding Window)

    滑动窗口基础 滑动窗口常用来解决求字符串子串问题,借助map和计数器,其能在O(n)时间复杂度求子串问题.滑动窗口和双指针(Two pointers)有些类似,可以理解为往同一个方向走的双指针.常用滑 ...

  5. SpringCloud(六)之 网关概念、Zuul项目搭建-(利用Zuul 实现鉴权和限流实战)

    一.网关概念 1.什么是路由网关 网关是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能 提供路由请求.鉴权.监控.缓存.限流等功能.它将"1对N"问题转换成 ...

  6. Sentinel源码解析三(滑动窗口流量统计)

    前言 Sentinel的核心功能之一是流量统计,例如我们常用的指标QPS,当前线程数等.上一篇文章中我们已经大致提到了提供数据统计功能的Slot(StatisticSlot),StatisticSlo ...

  7. .NET服务治理之限流中间件-FireflySoft.RateLimit

    概述 FireflySoft.RateLimit自2021年1月发布第一个版本以来,经历了多次升级迭代,目前已经十分稳定,被很多开发者应用到了生产系统中,最新发布的版本是3.0.0. Github:h ...

  8. 基于令牌桶算法实现的SpringBoot分布式无锁限流插件

    本文档不会是最新的,最新的请看Github! 1.简介 基于令牌桶算法和漏桶算法实现的纳秒级分布式无锁限流插件,完美嵌入SpringBoot.SpringCloud应用,支持接口限流.方法限流.系统限 ...

  9. tcp协议头窗口,滑动窗口,流控制,拥塞控制关系

    参考文章 TCP 的那些事儿(下) http://coolshell.cn/articles/11609.html tcp/ip详解--拥塞控制 & 慢启动 快恢复 拥塞避免 http://b ...

  10. 【Distributed】限流技巧

    一.概述 1.1 高并发服务限流特技 1.2 为什么要互联网项目要限流 1.3 高并发限流解决方案 二.限流算法 2.1 计数器 2.2 滑动窗口计数 2.3 令牌桶算法 使用RateLimiter实 ...

随机推荐

  1. css实现按钮点击水波纹效果和两边扩散效果

    废话少说,先上代码了,复制到html中即可使用 点击查看代码 <!DOCTYPE html> <html lang="en"> <head> & ...

  2. KafkaProducerDemo

    package com.lxw.kafkademo; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache ...

  3. 感悟:FPGA的串行及并行设计思路

    前言 FPGA设计过程中, 会遇到大量的串行转并行或者并行转串行的问题; 这些问题主要体现在FPGA对于速度和面积的均衡上; 一般而言, FPGA使用并行的设计可以提高处理的速度, 消耗更多的资源; ...

  4. 可变形卷积系列(一) 打破常规,MSRA提出DCNv1 | ICCV 2017 Oral

    论文提出可变形卷积帮助模型高效地学习几何变换能力,能够简单地应用到分类模型和检测模型中,思想新颖,效果显著,十分值得学习   来源:晓飞的算法工程笔记 公众号 论文: Deformable Convo ...

  5. SQL优化篇之-如何减少耗时查询的调用次数

    函数调用次数与性能 在查询语句中,如果 Select 子句调用了较为耗时的函数或子查询,需要特别考虑函数调用次数对于SQL整体执行时间的影响. 一.数据准备,SQL 语句 模拟较耗时的用户函数 确保执 ...

  6. c语言的一些类型声明符

    基本类型: char: 字符类型 int: 整数类型 float: 单精度浮点数类型 double: 双精度浮点数类型 void: 无类型 修饰符: short: 短整数类型 long: 长整数类型 ...

  7. #状压dp#洛谷 3959 [NOIP2017 提高组] 宝藏

    题目 选定一个起点 \(S\),找到一棵生成树,最小化 \[\sum_{i=1}^n dep_i\times dis_i \] \(n\leq 12\) 分析 设 \(dp[d][S]\) 表示当前树 ...

  8. OpenHarmony开发之MQTT讲解

      相信MQTT这个名称大家都不陌生,物联网的开发必然会遇到MQTT相关知识的应用.那么什么是MQTT?它有什么特点?它能解决什么问题?它是如何工作的?OpenAtom OpenHarmony(以下简 ...

  9. js推送网页到扩展屏上

    需求: 电脑上有两个屏幕,想在主屏上的网页中点击一个按钮,副屏就可以显示需要推送过去的网页 实现方法: 本方法使用的是js来实现的,亲测可行,支持火狐,但是不支持谷歌 demo: 主屏网页:1.htm ...

  10. 推荐一个计算Grad-CAM的Python库

    前言 类激活图CAM(class activation mapping)用于可视化深度学习模型的感兴趣区域,增加了神经网络的可解释性.现在常用Grad-CAM可视化,Grad-CAM基于梯度计算激活图 ...