使用Redis Lua脚本实现高级限流策略

引言

在现代的Web应用中,限流是一个非常重要的功能,它帮助我们控制对某些资源的访问频率,以防止系统过载和滥用。Redis是一个高性能的键值存储系统,它的原子操作和Lua脚本功能为实现复杂的限流策略提供了强大的支持。本文将详细介绍一个使用Redis Lua脚本实现的高级限流策略。

理解限流Lua脚本

Lua脚本是Redis中一种强大的功能,它可以在服务器端执行复杂的逻辑,而无需在客户端进行多次调用。这对于实现限流逻辑来说是非常有用的,因为它可以保证限流操作的原子性。

下面是一个用于限流的Lua脚本示例:

-- 获取KEY
local limitResourceKey = KEYS[1]
-- 限流时间窗口(毫秒)
local limitTimeWindowMillis = tonumber(ARGV[1])
-- 当前时间(毫秒)
local currentMillis = tonumber(ARGV[2])
-- 最大次数
local limitCount = tonumber(ARGV[3])-- 窗口开始时间
local windowStartMs = currentMillis - limitTimeWindowMillis
-- 获取key的次数
local current = redis.call('zcount', limitResourceKey, windowStartMs, currentMillis)-- 如果key的次数存在且大于预设值直接返回false
if current and tonumber(current) >= limitCount thenreturn false
end-- 清除所有过期成员
redis.call("ZREMRANGEBYSCORE", limitResourceKey, 0, windowStartMs)-- 添加当前成员
math.randomseed(currentMillis)
local uniqueId = tostring(currentMillis) .. tostring(math.random(1000, 9999))
redis.call("zadd", limitResourceKey, currentMillis, uniqueId)
redis.call("expire", limitResourceKey, limitTimeWindowMillis / 1000)-- 返回true表示操作成功,没有超出限流
return true

脚本解析

1. 获取参数

脚本首先获取三个参数:限流的键(limitResourceKey)、时间窗口大小(limitTimeWindowMillis)和当前时间(currentMillis)。此外,还有一个最大请求次数的参数(limitCount)。

2. 计算窗口开始时间

使用当前时间和时间窗口大小计算出窗口的开始时间(windowStartMs),这个时间用于确定计数的起始点。

3. 计数

使用zcount命令来获取在当前时间窗口内已经记录的请求次数。zcount是一个有序集合的命令,它可以用来获取指定分数区间的成员数量。

4. 检查是否超出限流

如果当前的请求次数加上即将到来的请求已经超过了设定的最大次数,则直接返回false,表示请求被限流。

5. 清除过期成员

使用ZREMRANGEBYSCORE命令来清除时间窗口之外的过期请求记录,确保有序集合中只包含当前时间窗口内的请求记录。

6. 添加当前请求

使用zadd命令添加当前请求的记录,同时使用math.random生成一个随机数来确保成员的唯一性。然后设置这个键的过期时间,以便自动清理。

7. 返回结果

如果脚本执行到这里,说明请求没有超出限流,返回true

使用场景

这个Lua脚本可以在多种场景中使用,例如API的限流、秒杀系统的请求控制等。通过将这个脚本集成到你的应用程序中,你可以有效地控制对关键资源的访问频率。

结语

通过使用Redis的Lua脚本功能,我们可以高效且安全地实现复杂的限流逻辑。这种方法不仅减少了网络延迟,还保证了限流操作的原子性,从而提高了系统的稳定性和可靠性。希望本文能够帮助你更好地理解和应用Redis Lua脚本来实现限流策略。

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

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

相关文章

day50 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 392.判断子序列

1143. 最长公共子序列 提示 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删…

大腾智能,基于云原生的国产工业协同平台

大腾智能是一家基于云原生的国产工业软件与数字化协同平台,专注于推动企业数字化转型与升级,为企业提供一系列专业、高效的云原生数字化软件及方案,推动产品设计、生产及营销展示的革新,实现可持续发展。 大腾智能旗下产品 3D模型…

USB2.0学习4--USB包结构和包类型

目录 1. USB包基本结构 1.1 SOP域(Start Of Packet) 1.2 SYNC域(同步域) 1.3 PID域(标识域) 1.4 地址域(ADDR) 1.5 帧号域(Fram) 1.6 数据域&#xff…

前端也需要知道的一些常用linux命令

前端也需要知道的一些常用linux命令 1.问题背景2.连接工具(SecureCRT_Portable)a.下载工具b.连接服务器c.登录到root账户 3.基本命令a.cd命令和cd ..b.ll命令和ls命令c:cp命令d.rm命令e:rz命令f.unzip命令g.mv命令h.pwd命令(这里没有用到&…

机器学习之支持向量机丨神经网络测试

选择题 SVM中的什么是支持向量? 【 正确答案: D】 A. 数据集中的所有样本 B. 模型参数 C. 模型的预测输出 D. 训练数据中离决策边界最近的样本点 支持向量机(SVM)算法的主要目标是: 【 正确答案: C】 A. 最小化间隔 B. 最小化损失函数 C. 最大化间隔 D.…

【LinuxC语言】TCPIP的经典5层结构

文章目录 前言TCP/IP的结构结构示意图结构的含义生活中的TCP/IP例子总结前言 TCP/IP,全称传输控制协议/因特网互联协议,是用于在互联网上进行数据交换的一组协议,形成了互联网的基础。TCP/IP的经典五层结构包括:物理层、数据链路层、网络层、传输层和应用层。这些层次各自…

CSS 相对父级固定,且不随滚动条滚动

CSS 相对父级固定&#xff0c;且不随滚动条滚动 <div class"parent"><div class"child-one">我是固定位置的子元素</div><div class"child-tow">我是滚动的子元素</div> </div>.parent {height: 200px; /*…

以正合,以奇胜,守正出奇,稳健

个人感觉说实话&#xff0c;在所里待的这几年&#xff0c;尤其是后两年&#xff0c;收获颇多&#xff0c;不管是智识上的&#xff0c;还有一堆兄弟&#xff0c;还有愿意分享和帮助我的老师们。 不管是搞科研还是做生意&#xff0c;稳健&#xff0c;在所里的时候&#xff0c;有…

Python-天天基金网爬虫分析

1.主题式网络爬虫名称&#xff1a;天天基金网爬虫分析 2.主题式网络爬虫爬取的内容与数据特征分析&#xff1a;通过访问天天基金的网站&#xff0c;爬取相对应的信息&#xff0c;最后保存下来做可视化分析。 3.主题式网络爬虫设计方案概述&#xff08;包括实现思路与技术难点…

益百分4.0版益生君重磅来袭,为您保驾护航

益百分4.0版益生君重磅来袭&#xff0c;为您保驾护航 暑期来临&#xff0c;很多人们终于等来了一年中最幸福的时刻&#xff0c;三五成群、结伴旅游成为他们选择欢度暑假的方式。 全国各地的旅游景点也迎来了旺季&#xff0c;各大旅游公司也推出了各种各样的旅游团购活动&#x…

FFmpeg交叉编译报错pkg-config not found

ffmpeg交叉编译时报错&#xff1a; WARNING: arm-linux-gnueabihf-pkg-config not found, library detection may fail.不慌&#xff0c;没有就下载嘛&#xff0c;直接install&#xff1a; sudo apt-get install pkg-config-arm-linux-gnueabihf 参考&#xff1a; How To I…

C++面试八股文:std::deque用过吗?

100编程书屋_孔夫子旧书网 某日二师兄参加XXX科技公司的C工程师开发岗位第26面&#xff1a; 面试官&#xff1a;deque用过吗&#xff1f; 二师兄&#xff1a;说实话&#xff0c;很少用&#xff0c;基本没用过。 面试官&#xff1a;为什么&#xff1f; 二师兄&#xff1a;因为使…

[学习笔记]3GPP R18宣布冻结,对物联网的影响是哪些?

6月18日&#xff0c;在上海举行的3GPP RAN&#xff08;无线接入网络项目&#xff09;第104次会议上&#xff0c;5G-A的第一代技术标准R18标准正式冻结。R18标准从立项到冻结历时3年多&#xff0c;是5G标准的第四版&#xff0c;也是面向5G-Advanced&#xff08;5G-A&#xff09;…

API-事件对象

学习目标&#xff1a; 掌握事件对象 学习内容&#xff1a; 获取事件对象事件对象常用属性trim方法案例 获取事件对象&#xff1a; 事件对象是什么 也是个对象&#xff0c;这个对象里有事件触发时的相关信息。 例如&#xff1a;鼠标点击事件中&#xff0c;事件对象就存了鼠标…

未来几年大多数人会面临的困境

未来几年&#xff0c;以下几个社会现象将会成为现实&#xff0c;希望这些相关行业的从业者早做准备&#xff0c;未雨绸缪。 一、就业难将会成为常态 就业将会越来越难、最近三年曾经如日中天的互联网企业在裁员降薪、曾经的用工大户也在裁员、不少倒闭破产的中小企业主也加入…

蓝牙ble数传芯片推荐,TD5327A芯片蓝牙5.1—拓达半导体

蓝牙数传芯片TD5327A芯片是一款支持蓝牙BLE的纯数传芯片&#xff0c;蓝牙5.1版本。芯片的亮点在于性能强&#xff0c;除了支持APP端直接对芯片做设置与查询操作&#xff0c;包括直接操作蓝牙芯片自身的IO与PWM口以外&#xff0c;还支持RTC日历功能&#xff0c;可以做各类定时类…

深度学习工具jupyter的new没有环境选项以及遇到的EnvironmentLocationNotFound:Not such a environment

jupyter安装使用 安装完Anaconda&#xff08;安装Anaconda具体请参考其他教程&#xff09;后&#xff0c;一般默认有安装jupyter打开 注意当前是base环境&#xff0c;后期使用jupyter需要切换环境 我们找到文件地址。用记事本打开 可以搜索&#xff1a;c.NotebookApp.noteb…

Redis规范

1 键值对的建议 1.1、key名建议&#xff1b; 建议key name设计&#xff1a;业务名:表名:id 比如&#xff1a; set school:student:1 martin 要求&#xff1a;不包含特殊字符 1.2、string 类型控制在10 KB以内&#xff0c;hash、list、set、zset元素个数不要超过5000&#…

C++的工厂模式与建造者模式连用

设计模式 工厂模式与建造者模式连用工厂模式建造者模式具体使用 工厂模式与建造者模式连用 工厂模式 工厂模式&#xff1a;是一种常用的设计模式&#xff0c;它属于创建型设计模式&#xff0c;旨在将对象的创建过程与使用过程分离&#xff0c;以实现解耦和灵活性。工厂模式通…

在Ubuntu 14.04上安装和配置SNMP守护程序和客户端的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 介绍 作为系统管理员的重要工作之一是收集关于服务器和基础设施的准确信息。有许多工具和选项可用于收集和处理这种类型的信息。其中许…