利用redis实现令牌桶限流

news/2024/4/27 10:16:51/文章来源:https://blog.csdn.net/hjxisking/article/details/130340919

lua脚本如下

argumentmean
ARGV[1]rate 「每秒生成几个令牌」
ARGV[2]burst 「令牌桶最大值」
ARGV[3]now_time「当前时间戳」
ARGV[4]get token nums 「开发者需要获取的token数」
KEYS[1]表示资源的tokenkey
KEYS[2]表示刷新时间的key
local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])
local fill_time = capacity/rate
local ttl = math.floor(fill_time*2)
local last_tokens = tonumber(redis.call("get", KEYS[1]))
if last_tokens == nil thenlast_tokens = capacity
endlocal last_refreshed = tonumber(redis.call("get", KEYS[2]))
if last_refreshed == nil thenlast_refreshed = 0
endlocal delta = math.max(0, now-last_refreshed)
local filled_tokens = math.min(capacity, last_tokens+(delta*rate))
local allowed = filled_tokens >= requested
local new_tokens = filled_tokens
if allowed thennew_tokens = filled_tokens - requested
endredis.call("setex", KEYS[1], ttl, new_tokens)
redis.call("setex", KEYS[2], ttl, now)return allowed

redis 的eval命令是用来执行lua脚本的

命令格式:EVAL script numkeys key [key …] arg [arg …]

  • script 参数是一段 Lua5.1 脚本程序。脚本不必(也不应该[^1])定义为一个 Lua 函数
  • numkeys 指定后续参数有几个key,即:key [key …]中key的个数。如没有key,则为0
  • key [key …] 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key)。在Lua脚本中通过KEYS[1], KEYS[2]获取。
  • arg [arg …] 附加参数。在Lua脚本中通过ARGV[1],ARGV[2]获取。
// 例子:使用redis为lua内置的redis.call函数
//      脚本内容为:先执行SET命令,在执行EXPIRE命令(相当于执行SETEX key1 60 10)
//      numkeys=1,keys数组有一个元素userAge(代表redis的key)
//      arg数组元素中有两个元素:10(代表userAge对应的value)和60(代表redis的存活时间)
127.0.0.1:6379> EVAL "redis.call('SET', KEYS[1], ARGV[1]);redis.call('EXPIRE', KEYS[1], ARGV[2]); return 1;" 1 userAge 10 60
(integer) 1
127.0.0.1:6379> get userAge
"10"
127.0.0.1:6379> ttl userAge
(integer) 50

注意避坑

为什么now需要通过参数传递进去,而不是在脚本内部自己获取?我们先来看个例子

127.0.0.1:6379> eval "local now = redis.call('time')[1]; redis.call('set','now',now); return redis.call('get','now')" 0
(error) ERR Error running script (call to f_e745355f11745192bd45376618a34bec9145653b): @user_script:1: @user_script: 1: Write commands not allowed after non deterministic commands. Call redis.replicate_commands() at the start of your script in order to switch to single commands replication mode.

这是因为在Redis中time命令是一个随机命令(时间是变化的),出于主从数据一致性考虑,要求脚本必须是纯函数的形式,也就是说对于一段Lua脚本给定相同的参数,写入Redis的数据也必须是相同的,对于随机性的写入Redis是拒绝的,所以在Lua脚本中调用了随机命令之后禁止再调用写命令 

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

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

相关文章

opencv-python视频分析与目标跟踪

目录 光流 目标跟踪 一、光流 使用OpenCV光流分析,跟踪蚂蚁的轨迹: 代码实现: import numpy as np import cv2if __name__ __main__:cap cv2.VideoCapture(ant.mp4)# ShiTomasi 角点检测参数feature_params dict(maxCorners100,quali…

Python边缘检测之prewitt, sobel, laplace算子

文章目录 滤波算子简介具体实现测试 滤波算子简介 ndimage中提供了卷积算法,并且建立在卷积之上,提供了三种边缘检测的滤波方案:prewitt, sobel以及laplace。 在convolve中列举了一个用于边缘检测的滤波算子,统一维度后&#xf…

3.微服务项目实战---Nacos Discovery--服务治理

3.1 服务治理介绍 先来思考一个问题 通过上一章的操作,我们已经可以实现微服务之间的调用。但是我们把服务提供者的网络地址 ( ip ,端口)等硬编码到了代码中,这种做法存在许多问题: 一旦服务提供者地址…

精进云原生 - Dubbo 3.2 正式发布

作者:Dubbo 社区 我们非常高兴地宣布,Dubbo 3.2 已经正式发布了!这个版本带来了许多新功能和改进,这也是 Dubbo 在面对云原生化的当下的一次重要的尝试。 背景介绍 Apache Dubbo 是一款 RPC 服务开发框架,用于解决微…

虹科分享 | 如何主动保护个人信息 | 网络安全评级

网上报税和支付越来越流行,针对毫无防备的纳税人的税务欺诈也越来越频繁。以下是一些需要避免的常见网上税务骗局: 网络钓鱼诈骗 骗子利用电子邮件、短信或电话伪装成相关机构或报税软件提供商,诱骗人们提供他们的个人信息,或点击…

【云计算•云原生】1.什么是云计算?它为什么这么火?

文章目录 1.云计算基础什么是云计算云计算的分类开源软件、自由软件、免费软件 2.云计算机制云基础设施机制云管理机制云安全机制基本云架构 3.虚拟化技术服务器虚拟化服务器虚拟化技术CPU虚拟化内存虚拟化设备和I/O虚拟化存储虚拟化网络虚拟化桌面虚拟化 KVM 4.网络与存储基础…

实测有效!手把手带你将 Docker Image 体积减少 90%

Docker Image 体积越大,那部署要花的时间就越长;假如每个版本都有好几 GB,那并不是一个理想的状态;因此笔者开始动手实作,想看看到底能将 Docker Image 的体积缩小多少! 大纲 ㄧ、先初始化一个简易的 Node.js 专案 二、撰写 Dockefile,了解优化前体积有多大 三、使用 No…

通信算法之145:OFDM系统频偏(IFO/FFO)对频域信号影响

carrier frequency offset 1. 整数倍频偏IFO,频域数据相对发送端的数据出现了循环移位,子载波仍然正交。 2.小数倍频偏FFO,频域数据幅度和相位都发生变化,引入了ICI。 无频偏正常星座图 代码:待补充 读者1/2:

2023.4.23第五十次周报

目录 前言 文献阅读:基于ARIMA-WOA-LSTM模型的空气污染物预测 背景 ARIMA-WOA-LSTM模型 思路 主要贡献 积分移动平均自回归 (ARIMA) 鲸鱼优化算法 搜索超参数 CEEMDAN 结论 LSTM-Kriging 主要目标 理论猜想 问1&#xff1a…

Opencv+Python笔记(九)模板匹配

模板匹配 模板匹配常用于对象检测,且实现简单计算效率高。但如果输入图像中存在变化因素如旋转、缩放、视角变化等,模板匹配很容易失效 模板匹配原理: 1.匹配方式为模板 (a * b) 在原图像 (m * n) 上滑动 使用参数method中指定的方法&#…

IJKPLAYER源码分析-常用API

前言 本文简要介绍IJKPLAYER的几个常用API,以API使用的角度,来审视其内部运作原理。这里以iOS端直播API调用切入。 调用流程 init 创建播放器实例后,会先调用init方法进行初始化: - (IJKFFMediaPlayer *)init {self [super ini…

ChatGLM-6B 中文对话模型复现、调用模块、微调及部署实现(更新中)

ChatGLM-6B-PT 一、前言 近期,清华开源了其中文对话大模型的小参数量版本 ChatGLM-6B(GitHub地址:https://github.com/THUDM/ChatGLM-6B)。其不仅可以单卡部署在个人电脑上,甚至 INT4 量化还可以最低部署到 6G 显存的…

SLAM论文速递【SLAM—— RDS-SLAM:基于语义分割方法的实时动态SLAM—4.24(1)

论文信息 题目: RDS-SLAM:Real-Time Dynamic SLAM Using Semantic Segmentation Methods RDS-SLAM:基于语义分割方法的实时动态SLAM论文地址: https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber9318990发表期刊: IEEE Access ( Volum…

新手必看!ChatGPT常见问题总整理,你遇到了几个?

随着ChatGPT火爆全球,使用人数以指数型成长,许多使用上的问题呈现在网路上。 今天这篇文章会用实作的方式带大家了解ChatGPT有哪些常见问题,以此减少踩坑的机会。 并用简单的示例让大家感受GPT-3.5与GPT-4的能力差异,希望对大家有所帮助。 大家会有这些问题,其实就是希望…

SequoiaDB分布式数据库2023.3月刊

本月看点速览 赋能行业,参编《分布式数据库金融应用发展报告》 脱颖而出,入选2022专精特新黑马大赛年度十强 激烈角逐,成功晋级全国信创优秀解决方案决赛 新穗新彩,多家权威媒体走进巨杉 青杉计划2023持续进行,一起…

从源码全面解析 ArrayBlockingQueue 的来龙去脉

👏作者简介:大家好,我是爱敲代码的小黄,独角兽企业的Java开发工程师,CSDN博客专家,阿里云专家博主📕系列专栏:Java设计模式、数据结构和算法、Kafka从入门到成神、Kafka从成神到升仙…

安卓手机(微信小程序)抓蓝牙通信数据包

前言 因为公司需要......所以我就弄了一下,参考了很多别人的文章。 成果:它可以抓取微信小程序、安卓APP的蓝牙数据通信包。 开始 我是小米手机,所以我以我自己手机为例 通信过程操作 第一步 打开开发者选项,打开蓝牙调试日志和蓝牙数据包日志开关(如果两者只有其中…

MAVEN环境变量配置(Windows 11)

1、直接在搜索框中搜:编辑系统环境变量 2、点击环境变量 3、 在系统变量里面新建系统变量 变量名:MAVEN_HOME 变量值:路径一定要写到maven的bin目录下 以下这种写法是错误的 4、新建系统变量完成 5、 往下滑 找到path,可以双击…

什么是gpt一4-如何用上gpt-4

怎么使用gpt-4 目前GPT-4还未正式发布或公开,因此也没有详细的对接说明。但是我们可以根据GPT-4的前身GPT-3的应用经验,以及GPT-4的预期功能推测一些可能的使用步骤: 选择适合的GPT-4实现技术:GPT-4可能有不同的实现技术&#xff…

Opencv+Python笔记(八)轮廓检测

目录 一、轮廓的检测和绘制1.读入图像2.将读入图像转化为灰度图3.对灰度图进行二值化 [图像的阈值化处理](https://blog.csdn.net/Ggs5s_/article/details/130301816?spm1001.2014.3001.5501)4.进行轮廓检测5.在原图中显示轮廓 二、轮廓层级关系1.RET_LIST2.RETR_EXTERNAL3. R…