Redis第17讲——Redis zset结构实现滑动窗口限流

一、什么是滑动窗口限流

滑动窗口限流是一种流量控制策略,用于控制在一定时间内允许执行的操作数量或请求频率。它的工作方式类似于一个滑动时间窗口,对每个时间窗口的请求数量进行计数,并根据预先设置的限流策略来限制或调节流量,通常包括以下几个要素:

  • 时间窗口:限流的时间段,例如每秒、每分钟或每小时,窗口可以固定,也可以动态调整。

  • 滑动窗口:在整个事件窗口内滑动的小窗口,用于计算当前时间段内的请求数量。

  • 计数器:用于记录当前窗口内的请求数量数量。

  • 限流策略:预先设定的限流规则,例如允许的最大请求数量,以及如何处理超出限制的请求(例如拒绝、延迟处理)等。

ps:目前主流的限流算法有令牌(Gateway、Ratelimiter)、漏桶(Nginx)、滑动窗口(Sentinel)。

二、为什么需要限流

  • 防止滥用:通过限制每个用户或IP地址的请求频率,可以防止恶意用户或攻击者对系统进行滥用,例如DOS攻击。

  • 防止过载:当大量请求同时到达系统时,如果系统无法合理地处理这些请求,可能会导致系统资源被耗尽,甚至崩溃。

三、工作原理

假设我们时间窗口设为每分钟,那么红色窗口内的时间段就是滑动窗口,如下图:

当时间窗口移动时,需要把上一个时间段中的请求数量给减掉,当有新请求或操作进来时,系统会检查窗口内的计数是否已满,如果没满,请求允许执行,反之触发限流策略,比如被拒绝或者进入等待队列。

就拿上图举个例子,当前时间为12:00,计数器为200个,也就是每分钟允许的请求数量为200个,当12点零59秒第201个请求进来了,那么会直接触发限流策略。假设到了12点一分零1秒,系统会把12点至12点零一分的请求数量给移除。

四、Redis实现滑动窗口限流

在Redis中,我们可以用ZSET来实现这个功能。

key可以为请求的资源名,例如根据ip限制访问资源流量,那么key就可以设置为资源名+ip地址,score为当前请求的时间戳,member建议用请求详情的hash进行存储(或者UUID、MD5),避免在并发时,时间戳一致出现score和member一样导致的幂等问题。

代码如下:

public class LimitWindows {//计数器private final static long limit = 100;public boolean allowRequest(Jedis jedis,String key){//当前时间long currentTime = System.currentTimeMillis();//窗口开始时间:当前时间-60slong windowStart = System.currentTimeMillis() - 60*1000;//删除窗口开始时间之前的所有数据jedis.zremrangeByScore(key,"-inf",String.valueOf(windowStart));//计算总请求数long current = jedis.zcard(key);//判断if(current<limit){//窗口足够则把当前请求加入jedis.zadd(key,currentTime,String.valueOf(currentTime));return true;}return false;}
}

以上高并发下可能会出现原子性问题,那么我们可以考虑用LUA脚本实现:

public class LimitWindows {//计数器private final static long limit = 100;public boolean allowRequest(Jedis jedis,String key){//获取当前时间戳long currentTime = System.currentTimeMillis();String luaScript = "local window_start_time = ARGV[1] -ARGV[3]*1000 " +" redis.call('ZREMRANGEBYSCORE',KEYS[1],'-inf',window_start_time) " +" local now_request = redis.call('ZCARD',KEYS[1]) " +" if now_request < tonumber(ARGV[2]) then " +" redis.call('ZADD',KEYS[1],ARGV[1],ARGV[1]) " +"     return 1 " +"else " +"      return 0 " +" end ";Object result = jedis.eval(luaScript, 1, key, String.valueOf(currentTime), String.valueOf(limit), String.valueOf(60));return (long) result == 1;}
}

ps:"-inf"在reids中表示负无穷,"+inf"表示正无穷

End:希望对大家有所帮助,如果有纰漏或者更好的想法,请您一定不要吝啬你的赐教🙋。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/13317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

maven deploy项目发布到中央仓库GPG签名失败signing failed: No secret key

maven deploy项目发布到中央仓库GPG签名失败signing failed: No secret key 执行操作 在我执行命令打包项目到中央仓库时失败 mvn clean deploy错误信息 [INFO] --- gpg:3.1.0:sign (sign-artifacts) LocalCache --- [INFO] Signing 4 files with 9961AA14xxxxxxxxxxxxxxD…

Ps 滤镜:彩色铅笔

Ps菜单&#xff1a;滤镜/滤镜库/艺术效果/彩色铅笔 Filter Gallery/Artistic/Colored Pencil 彩色铅笔 Colored Pencil滤镜用于模拟用彩色铅笔手绘的艺术效果&#xff0c;它能够在纯色背景上重新绘制图像&#xff0c;同时保留边缘细节并显示出粗糙的阴影线。此滤镜特别适合用于…

STM32HAL库-中断篇

中断 中断简介 中断是一种事件处理机制&#xff0c;可以暂停主程序的运行&#xff0c;转而处理特定事件程序。 中断的作用和意义&#xff1a; 实时控制 在确定事件内对响应事件做出相应 故障处理 检测到故障需要第一时间处理 数据传输 如串口通信&#xff0c;不确定数…

Mamba:7 VENI VIDI VICI

若在阅读过程中有些知识点存在盲区&#xff0c;可以回到如何优雅的谈论大模型重新阅读。另外斯坦福2024人工智能报告解读为通识性读物。若对于如果构建生成级别的AI架构则可以关注AI架构设计。技术宅麻烦死磕LLM背后的基础模型。 序列模型的效率与有效性之间的权衡取决于状态编…

实锤,阿里云盾会拦截百度云防护的IP!

今天凌晨&#xff0c;一位站长联系上云加速客服&#xff0c;反馈说&#xff0c;网站突然出现了502的情况。 在检查云防护子域名配置没有问题、本地强制回源没有问题的情况下&#xff0c;我们得出结论是要么服务器内防火墙拦截了云防护的IP段&#xff0c;要么服务器商拦截了云防…

分布式计算、并行计算、网格计算、边缘计算

分布式计算 分布式计算是一种计算方法&#xff0c;它将一个大型的计算任务分解成多个子任务&#xff0c;并将这些子任务分布在网络上的多台计算机&#xff08;节点&#xff09;上同时执行。这些节点通过通信网络协同工作&#xff0c;共同完成任务。每个节点可以独立处理自己的…

如何使用AzurEnum快速枚举Microsoft Entra ID(Azure AD)

AzurEnum是一款针对Azure的安全工具&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以轻松快速地枚举Microsoft Entra ID&#xff08;Azure AD&#xff09;。 该工具基于纯Python 3开发&#xff0c;可以在Windows和Linux系统上运行&#xff0c;但考虑到性能和稳定性&a…

远程桌面如何配置?使用快解析远程访问

远程桌面如何设置&#xff1f; 远程桌面作为windows系统内置的一个组件&#xff0c;多年来深受用户喜爱。使用此功能&#xff0c;我们能够轻而易举的控制我们想要控制的电脑。下面我就简单的介绍一下远程桌面的设置方法。 在讲具体设置方法之前&#xff0c;首先应该给大家普及…

dfs记忆化搜索,动态规划

动态规划概念&#xff1a; 给定一个问题&#xff0c;将其拆成一个个子问题&#xff0c;直到子问题可以直接解决。然后把子问题的答案保存起来&#xff0c;以减少重复计算。再根据子问题的答案反推&#xff0c;得出原问题解。 821 运行时间长的原因&#xff1a; 重复大量计算…

MLM之GPT-4o:GPT-4o(多模态/高智能/2倍速/视觉改进/128K的大窗口)的简介、安装和使用方法、案例应用之详细攻略

MLM之GPT-4o&#xff1a;GPT-4o(多模态/高智能/2倍速/视觉改进/128K的大窗口)的简介、安装和使用方法、案例应用之详细攻略 导读&#xff1a;2024年5月13日&#xff0c;OpenAI重磅发布新旗舰模型GPT-4o&#xff0c;这是一个全新的旗舰模型&#xff0c;可以实时跨越音频、视觉和…

Unity Render入门

概述 在unity中渲染相关的组件是和Render关联的&#xff0c;比如我们常见的3D模型中的MeshRender&#xff0c;UI中的RenderCanvas等都是和Render相关联的&#xff0c;相信在unity的学习过程中&#xff0c;一定看到过非常多和Render相关的内容&#xff0c;那让我们学习一下这部…

python批量生成防伪识别二维码

欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.代码 三.使用 四.总结 一.前言 二维码(QR Code)是一种矩阵条码技术,它使用黑白矩形图案来表示二进制数据,这些矩形图案可以被设备扫描并解读。二维码可以被用来存储

每日一题——PAT(乙级)1002 写出这个数(举一反三、思想解读)

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三题目链接 我的写法&#xff1a; nums_sounds{0:ling,1:yi,2:er,3:san,4:si,5:wu,6:liu,7:qi,8:ba,9:jiu, }sum0inputsinput() input_nums[] for i i…

绝地求生:29.2商城更新内容预览:挣脱尘网通行证,经典皮肤返场,空投活动

就在今天历经9小时维护&#xff0c;29.2版本终于上线&#xff0c;柠檬茶带大家一起看看&#xff0c;这次游戏里都更新了哪些内容吧。 挣脱尘网通行证 豪华版&#xff1a;$14.99 普通版&#xff1a;$4.99 豪华版比普通版多10级升级券和2套生存者宝箱 分支一 分支二 分支三 额外…

现代加密技术(对称和非对称加密)

1.分类 现代加密技术&#xff1a;对称和非对称加密&#xff0c;对称加密即共享密钥&#xff0c;非对称加密是公钥加密算法。 2.基础总结 AES是什么算法&#xff1f; 分组加密算法&#xff0c;对称加密算法AES的分组长度是&#xff1f;固定128位AES密钥长度是多少&#xff1f;支…

树莓派3B+入门(无外设)

昨日刚到一块树莓派3B&#xff0c;甚是喜爱&#xff0c;然半宿未眠 1、下载 在官网先下载烧录文件https://www.raspberrypi.com/software/ 下载完毕打开&#xff0c;选择&#xff0c;根据自己板子型号定 操作系统用最新的就行&#xff0c;64位不太稳定 储存卡&#xff0c;需…

C++ | Leetcode C++题解之第91题解码方法

题目&#xff1a; 题解&#xff1a; class Solution { public:int numDecodings(string s) {int n s.size();// a f[i-2], b f[i-1], c f[i]int a 0, b 1, c;for (int i 1; i < n; i) {c 0;if (s[i - 1] ! 0) {c b;}if (i > 1 && s[i - 2] ! 0 &&a…

24HN逆向部分wp

24H&N逆向部分wp 菜鸡新手师傅wp&#xff0c;Re 5/9&#xff0c;记录一下qaq&#xff08;好久没写博客了&#xff0c;水一篇hh&#xff09; 最喜欢的逆向题 64位&#xff0c;进主函数之后直接看&#xff0c;要求输入第5位为i&#xff0c;然后后面依次相等&#xff0c;长…

DevOps + 架构

一、DevOps 1定义 开发&#xff0c;测试&#xff0c;运维&#xff0c;甚至运营。出一个东西&#xff0c;就能马上走完一个流程&#xff0c;看效果 软件交付的速度和质量很重要 二、架构 1、解决系统复杂度 首先找到系统复杂度在哪里。 经典案例&#xff1a; 假设我们需要设…

Vue3实战笔记(22)—路由Vue-Router 实战指南(路由传参)

文章目录 前言一、路由router-link二、路由传参1.query方式2.params方式3.props传参 总结 前言 vue-router 是 Vue.js 官方路由管理器。它和 Vue.js 核心深度集成&#xff0c;让用 Vue.js 构建单页应用变得易如反掌。 前面提到过简单的使用路由&#xff0c;直到上文使用404界面…