利用 Redis 和 Lua 实现高效的限流功能

简介

在现代系统中,限流是一种重要的机制,用于控制服务端的流量并保护系统免受恶意攻击或请求泛滥的影响。本文将介绍如何利用 Redis 和 Lua 结合实现高效的限流功能。

一、什么是限流

限流指的是对系统中的请求进行控制和调节,确保系统在承受压力时能够正常运行,不会因为突然的大量请求导致系统宕机或服务质量下降。限流在系统中具有至关重要的作用,可以平稳地处理请求流量,防止系统过载。

二、什么是Redis

Redis是一个高性能的内存数据库,具有快速的读写速度和丰富的数据结构支持。在限流场景中,Redis可以作为一个高效的缓存和计数工具,帮助实现限流功能。

三、什么是lua

Lua是一种轻量级的脚本语言,它具有简洁的语法和高效的执行性能。

四、限流要用lua+Redis而不用Java、Python 等语言呢?

  • 性能和原子性: Lua脚本可以在Redis服务器端原子性地执行多个命令,避免了多次网络通信的开销,提高了性能和原子性。相比之下,用Java或Python实现的限流算法需要多次与Redis进行通信,性能相对较低。

  • 便捷性: Lua脚本可以直接在Redis服务器端执行,无需额外部署其他语言的运行环境,更加灵活和便捷。

  • Redis支持: Redis天然支持Lua脚本,可以直接执行,不需要额外的配置和插件。而如果使用Java或Python,需要额外的库或框架来与Redis进行交互。

五、限流算法选择

5.1 令牌桶算法

令牌桶算法中,存在一个令牌桶,可以往桶中添加令牌。每个令牌代表一个处理请求的许可。如果请求到了,桶中有足够的令牌,择允许处理该请求,同时消耗相应数量的令牌。如果桶中没有足够的令牌,则拒接该请求或将请求放入队列等待令牌。

5.2 漏桶算法

漏桶算法中,存在一个固定容量的漏桶,以固定的速率处理请求。如果请求到来,放入漏桶中,如果漏桶已满,则拒绝请求,如果漏桶未满,则按照固定的速率处理请求。

六、lua+Redis实现令牌桶算法

local key = KEYS[1] -- 获取传入lua脚本的第一个keys参数,用作存储令牌数目的键名
local limit = tonumber(ARGV[1]) -- 将传入lua脚本的第一个ARGV参数转换为整数,表示桶的容量
local current = tonumber(redis.call('get', key) or "0")
-- 通过Redis的GET命令获取当前令牌桶中的令牌数量,如果没有获取到则默认为0,并将其转换为整数。
​
if current + 1 > limit then -- 判断当前令牌桶中的令牌数量加1后是否超过阈值return 0 -- 超过表示请求被限流,返回0
elseredis.call('INCR', key) -- 通过Redis的INCR命令将令牌桶中的数量加1,表示通过了一个请求redis.call('EXPIRE', key, ARGV[2]) -- 设置令牌桶的过期时间为ARGV 参数中指定的时间return 1  -- 返回1,表示通过限流检查
end

七、lua+Redis实现漏桶算法

local key = KEYS[1] -- 限流器的键名
local capacity = tonumber(ARGV[1]) -- 漏桶的容量
local rate = tonumber(ARGV[2]) -- 漏桶的速率
local now = tonumber(ARGV[3]) -- 当前时间戳
local interval = 1 / rate -- 时间间隔,即每个请求需要等待的时间
​
local water = tonumber(redis.call('get', key) or "0") -- 获取漏桶中的水滴数量
local lastLeakTime = tonumber(redis.call('get', key .. ':last_leak_time') or "0") -- 上次漏水的时间戳
​
local elapsed = math.max(0, now - lastLeakTime) -- 计算当前时间与上次漏水的时间间隔
​
water = water - elapsed * rate -- 根据时间间隔计算漏水数量,并更新漏桶中的水滴数量
​
if water < 0 thenwater = 0 -- 水滴数量不会低于0
end
​
water = water + 1 -- 新的请求加入漏桶中
​
if water > capacity thenreturn 0 -- 漏桶已满,拒绝请求
elseredis.call('set', key, water) -- 更新漏桶中的水滴数量redis.call('set', key .. ':last_leak_time', now) -- 更新上次漏水的时间戳return interval -- 返回请求需要等待的时间间隔
end

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

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

相关文章

1908_Arm Cortex-M3的实现

1908_Arm Cortex-M3的实现 全部学习汇总&#xff1a; g_arm_cores: ARM内核的学习笔记 (gitee.com) 这是第一次看一份这样的手册&#xff0c;之前的MCU编程基本上就是专注于软件接口方面。而OS等方面的一些功能基本上都是用了现成的解决方案&#xff0c;因此也就没有过多的关注…

hdu-2047(dp做法)

hdu-2047 阿牛的EOF牛肉串 其他博客递一维推做法比较难想(我不会 升到二维简单很多&#xff0c;dp[i][j]表示长度为i时&#xff0c;最后一个字母为j #include<bits/stdc.h>using namespace std; const int maxn 5e6 5; const double pi 3.1415927; const int mod 100…

阿里二面,redis宕机了,如何快速恢复数据

背景 有个同学阿里二面&#xff0c;面试官问&#xff1a;redis宕机了&#xff0c;如何恢复数据&#xff1f; 这位同学当时一脸懵&#xff0c;不知道如何回答。 分析分析这个问题&#xff0c;redis宕机&#xff0c;要想恢复数据&#xff0c;首先redis的数据有没有做持久化&…

C if 语句

一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。 语法 C 语言中 if 语句的语法&#xff1a; if(boolean_expression) {/* 如果布尔表达式为真将执行的语句 */ }如果布尔表达式为 true&#xff0c;则 if 语句内的代码块将被执行。如果布尔表达式为 false&#xff0c;…

JavaScript构造函数模式:创建对象的另一种方式!

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

kafka(三)springboot集成kafka(1)介绍

一、相关组件介绍 1、pom&#xff1a; <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>3.0.0</version></dependency> </dependencies> 2、k…

【爬虫】单首音乐的爬取(附源码)

以某狗音乐为例 import requests import re import time import hashlibdef GetResponse(url):# 模拟浏览器headers {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0}# 发送请求…

Android开发环境搭建

第一步&#xff1a;Android Studio官网下载 官网&#xff1a;下载 Android Studio 和应用工具 - Android 开发者 | Android Developers (google.cn) 第二步&#xff1a;Android Studio安装 打开下载好的安装包。 改一下安装路径 点击ok即可。 点击next 继续next的 继续next…

android音视频编解码,你有过迷茫吗

3-5年的Android工程师最容易遇到的4个瓶颈是什么&#xff1f; 1.原理认知浅 工作内容多是简单UI界面开发和第三方SDK整合&#xff0c;对原理层和底层开发了解不深 2.技术视野窄 长期在小型软件公司&#xff0c;外包公司工作&#xff0c;技术视野被限制的太厉害 3.薪资提升…

flutter弹窗输入,Android学习的三个终极问题及学习路线规划

题库非常全面包括&#xff1a; Android基础知识: 基本涵盖Android所有知识体系&#xff0c;四大组件&#xff0c;Fragment,WebView,事件分发&#xff0c;View绘制…Java基础知识&高阶知识点: 基础部分不谈了&#xff0c;高阶部分&#xff1a;泛型&#xff0c;反射&#xff…

git使用教程14-Pycharm版本控制与分支管理

一、版本控制 1、版本控制介绍 &#xff08;1&#xff09;Version Control System 版本控制系统&#xff0c;简称VCS。 &#xff08;2&#xff09;版本控制系统分类&#xff1a; 集中式版本控制工具&#xff1a;SVN 分布式版本控制工具&#xff1a;Git 2、Pycharm 支持的版本…

EPSON RA8000CE (RTC模块)压电侠

RA8000CE是一个集成了32.768 kHz数字温度补偿晶体振荡器(DTCXO)的RTC模块。它包括各种功能&#xff0c;如具有闰年校正的秒到年时钟/日历&#xff0c;时间警报&#xff0c;唤醒计时器&#xff0c;时间更新中断&#xff0c;时钟输出和时间戳功能&#xff0c;可以在外部或内部事件…