基于Redis实现令牌桶算法
基于Redis实现令牌桶算法
- 令牌桶算法
- 算法流程图
- 优点
- 缺点
- 实现
- 其它限流算法
令牌桶算法
令牌桶是一种用于分组交换和电信网络的算法。它可用于检查数据包形式的数据传输是否符合定义的带宽和突发性限制(流量不均匀或变化的衡量标准)。它还可以用作调度算法来确定符合带宽和突发性限制设置的传输时序。
算法流程图
如图所示,令牌桶算法可以描述为:
- 令牌桶初始大小和容量为X
- 以一定速率Y向令牌桶中添加令牌,如果令牌桶满了,忽略多余令牌
- 每次请求令牌桶拿Z个令牌,如果当前令牌桶不足,则拒绝当前请求

优点
- 平滑流量:
令牌桶可以通过控制令牌放入速率(Y)平滑流量,防止过高负载导致系统崩溃 - 可以处理突发流量
令牌桶可以积累一定量的令牌以应对突发流量 - 灵活
通过调整令牌桶的容量和令牌放入速率,可以灵活地控制突发容量和请求的平均处理速率。这种灵活性使得令牌桶算法能够适应不同应用场景。
缺点
- 资源占用
令牌桶算法需要维护当前令牌数和上次放入时间, 这会耗费较高的计算资源。 - 参数调整复杂
令牌桶算法需要调整容量(X)、速率(Y)和每次请求令牌数量(Z),不合适的参数有可能导致请求分配不公平乃至饥饿请求(长时间无法获取到令牌的请求)。 - 依赖系统时间
令牌桶算法在计算令牌数量时依赖于系统时间。如果系统时间发生异常(如时间回拨),则可能会导致算法失效或产生不可预测的结果。
实现
本文是使用Redis的Lua脚本来实现的
--- 实现令牌桶算法
-- 以一定的频率向令牌桶中放入令牌, 其它人使用时获取令牌, 如果能够获取成功
local expire_time = 3600 -- 1个小时失效
local bucket_size = 20 -- 一个桶最多有20张令牌
local bucket_speed = 3.5 -- 每秒增加令牌的个数
local requests_token = 1 -- 请求一次耗费的令牌数local time = redis.call('TIME')
local current_time = time[1] * 1000 + time[2] / 1000 -- TIME返回的是 秒,纳秒. 这里转换成微秒
local token = KEYS[1]-- 获取当前剩余令牌数
local bucket = redis.call('HGETALL', token)
local ret = 0
if table.maxn(bucket) == 0 then-- 令牌桶已失效或者还没有设置redis.call('HSET', token, 'lastRefillTime', current_time)redis.call('HSET', token, 'tokensRemain', bucket_size - requests_token)redis.call('PEXPIRE', token, expire_time * 1500)ret = 1
else-- 上次填充时间local lastRefillTime = tonumber(bucket[2])-- 剩余令牌数local tokensRemain = tonumber(bucket[4])-- 距离上次调用时间local cost_time = current_time - lastRefillTimeif cost_time < 0 then-- 发生了时间回拨, 令牌不再增加current_time = lastRefillTimeif tokensRemain >= requests_token thentokensRemain = tokensRemain - requests_tokenret = 1endelseif tokensRemain >= 1 or cost_time * bucket_speed / 1000 >= requests_token thentokensRemain = math.min(tokensRemain + (cost_time * bucket_speed / 1000) - requests_token, bucket_size - requests_token)ret = 1elsetokensRemain = tokensRemain + (cost_time * bucket_speed / 1000)ret = 0endredis.call('HSET', token, 'lastRefillTime', current_time)redis.call('HSET', token, 'tokensRemain', tokensRemain)redis.call('PEXPIRE', token, expire_time * 1500)
end
return ret
其它限流算法
- 计数器算法
- 滑动窗口算法
- 漏桶算法
相关文章:
基于Redis实现令牌桶算法
基于Redis实现令牌桶算法 令牌桶算法算法流程图优点缺点 实现其它限流算法 令牌桶算法 令牌桶是一种用于分组交换和电信网络的算法。它可用于检查数据包形式的数据传输是否符合定义的带宽和突发性限制(流量不均匀或变化的衡量标准)。它还可以用作调度算…...
[Java] 使用 VSCode 来开发 Java
目录 前言Java 环境怎么看自己是否已经配置完成?安装 JDK安装 Maven 环境修改 Maven 依赖源 完善 VS Code配置插件配置 Maven配置 Maven Settings配置 Maven 可执行文件地址 前言 由于使用 VSCode 编码已经成为习惯,并且它确实相对其他的 IDE 较为轻量化…...
奇怪的知识又增加了,ESP32下的Lisp编程:ULisp--Lisp for microcontrollers
ESP32下有MicroPython,那么我就在想,有Lisp语言支持吗?答案是果然有!有ULisp,专门为MCU设计的Lisp! 网址:uLisp - Lisp for microcontrollers 介绍:用于微控制器的 Lisp 适用于 Ar…...
STM32标准库学习之寄存器方法点亮LED灯
STM32C8T6最小系统开发板,点亮PC13引脚的LED灯 1.使能PC13引脚的定时器 PC13引脚为GPIOC组的第13个端口,GPIO的时钟使能定时器为RCC_APB2ENR,这是可以从手册中得出的,如下图所示 从下图可以得出,若要使能GPIOC端口&a…...
Jenkins:持续集成与持续部署的利器
🐇明明跟你说过:个人主页 🏅个人专栏:《未来已来:云原生之旅》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、什么是Jenkins 2、Jenkins的起源 二、Jenkins的核心…...
概率论得学习和整理30: 用EXCEL 描述泊松分布 poisson distribution
目录 1 泊松分布的基本内容 1.1 泊松分布的关键点 1.1.1 属于离散分布 1.1.2 泊松分布的特点:每个子区间内概率相等 , λ就是平均概率 1.2 核心参数 1.3 pmf公式 1.4 期望和方差 2 例1:用EXCEL计算泊松分布的概率 3 比较λ不同值时…...
汽车SoC芯片及其安全岛设计与未来发展趋势(学习笔记)
SoC系列已发布多篇文章,之前应该发布到4.3章节,后续还有包含常见汽车SoC,SoC评价指标,产业链及发展趋势等,均见已发布完整版本付费资源,链接如下: 汽车SoC芯片及其安全岛设计与未来发展趋势&am…...
【排序算法】——选择排序
前言 排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列。所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小&#x…...
第十五章 Linux Shell 编程
15.1 Shell 变量 了解:Shell的功能 了解:Shell的种类 了解:Shell的调用 了解:Shell变量的概念 了解:Shell变量的定义 了解:Shell数组变量 了解:Shell内置变量 了解:双引号 和…...
【c++笔试强训】(第三十八篇)
目录 不相邻取数(动态规划-线性dp) 题目解析 讲解算法原理 编写代码 空调遥控(⼆分/滑动窗⼝) 题目解析 讲解算法原理 编写代码 不相邻取数(动态规划-线性dp) 题目解析 1.题目链接:不相…...
go 自己写序列化函数不转义
以map[int32]string转化为[]byte为例 背景:算法传给我一个map[int32]string类型的值(map的值本身是json转化成的string),我需要把这个值生成一个文件上传到OSS,但是发现通过url下载下来的文件里面有转义字符。 原因&a…...
一般行业安全管理人员考试题库分享
1.在高速运转的机械飞轮外部安装防护罩,属于(B)安全技术措施。 A.限制能量 B.隔离 C.故障设计 D.设置薄弱环节 2.生产经营单位的(B)是本单位安全生产的第一责任人,对落实本单位安全生产主体责任全面负责,具体履行安全生产管理职责。 A.全员 B…...
Marketo REST API 批量修改邮件内容
以下是更加细化的 使用 Marketo REST API 批量修改邮件内容 的步骤,详细解释每个阶段的操作,包括 API 的请求、数据处理及潜在问题解决。 前期准备工作 确保 Marketo API 访问权限 你需要 Marketo REST API 用户 和 API Role,有权限访问邮件资…...
《云原生安全攻防》-- K8s安全框架:认证、鉴权与准入控制
从本节课程开始,我们将来介绍K8s安全框架,这是保障K8s集群安全比较关键的安全机制。接下来,让我们一起来探索K8s安全框架的运行机制。 在这个课程中,我们将学习以下内容: K8s安全框架:由认证、鉴权和准入控…...
淘宝获取sku详细信息 API
淘宝获取 SKU 详细信息的 API 主要是 taobao.item_sku 接口,以下是详细介绍: 公共参数 key:调用 key,是调用接口的身份验证信息,必须以 GET 方式拼接在 URL 中1.secret:调用密钥,与 key 配合使…...
基于Spring Boot的体育商品推荐系统
一、系统背景与目的 随着电子商务的快速发展和人们健康意识的提高,体育商品市场呈现出蓬勃发展的态势。然而,传统的体育商品销售方式存在商品种类繁多、用户选择困难、个性化需求无法满足等问题。为了解决这些问题,基于Spring Boot的体育商品…...
C++小细节笔记
1、C字符串转数字 – 数字转字符串 //string > int 使用 stoi stol//int > string 使用 to_string()2、C遍历 int evalRPN(vector<string>& tokens) {stack<int> intStack;for(string &str:tokens){}bool isValid(string s) {stack<char> …...
go语言并发读写数据队列,不停写的同时,一次最多读取指定量数据(逐行注释)
1、数据队列可以存储任意类型的一个数据(下程序是添加整数值)。 数据队列代码点这里查看《go语言结构体实现数据结构队列(先进先出)存储数据(逐行注释)》 2、读写操作并发进行(下程序向队列中…...
密码学——密码学概述、分类、加密技术(山东省大数据职称考试)
大数据分析应用-初级 第一部分 基础知识 一、大数据法律法规、政策文件、相关标准 二、计算机基础知识 三、信息化基础知识 四、密码学 五、大数据安全 六、数据库系统 七、数据仓库. 第二部分 专业知识 一、大数据技术与应用 二、大数据分析模型 三、数据科学 密码学 大数据…...
【数据库MySQL篇二】MySQL数据库入门基础教程:一网打尽数据库和表各种操作、命令和语法
一、MySQL创建数据库 使用Create命令创建数据库 我们可以在登陆 MySQL 服务后,使用 create 命令创建数据库,语法如下: CREATE DATABASE 数据库名; 以下命令简单的演示了创建数据库的过程,数据名为 RUNOOB: [roothost]# mysql -u root -p…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
