首页 > 数据库 >Redis+lua 实现令牌桶限流算法

Redis+lua 实现令牌桶限流算法

时间:2023-04-27 19:35:45浏览次数:35  
标签:令牌 -- res Redis lua amount 限流 time local

使用

lua := redis.NewScript(script)
args[0] = strconv.Itoa(fillInterval)
args[1] = strconv.FormatInt(time.Now().Unix()*1000, 10)
res, err := lua.Run(context.Background(), utils.Red, []string{"RateLimit"}, args[0], args[1]).Result()
-- 定义返回值res[1]是否触发限流(1限流 0通过)res[2]当前桶中的令牌数
local res={}
res[1]=0
--local curtime=redis.call('time')
local inteval_time=tonumber(ARGV[1]) -- 放入令牌桶的间隔时间
local current_time=tonumber(ARGV[2]) -- 当前时间

local amount=10 -- 一次取几个
local key_expire_time=1000*3600 -- 过期时间
local inflow__per_unit=100 -- 每次放多少
local capacity=1000
local st_key='last_update'
local bucket_amount = 0

-- 上次向桶中投放令牌的时间
local last_time=redis.call('get',st_key)
-- 当前令牌数
local current_value = redis.call('get',KEYS[1])

if(last_time == false or current_value == false) -- 令牌桶也不存在或过期,重新生成令牌桶
then
    bucket_amount = capacity - amount;
    -- 生成令牌桶
    redis.call('set',KEYS[1],bucket_amount,'PX',key_expire_time)
    -- 设置投放时间
    redis.call('set',st_key,current_time,'PX',key_expire_time)
    res[2]=bucket_amount
    return res
end

current_value = tonumber(current_value)
last_time=tonumber(last_time)
local past_time=current_time-last_time --当前时间-上次投放的时间
if(past_time<inteval_time)
then
    -- 不到放入令牌时间,直接从令牌桶中取走令牌
    bucket_amount=current_value-amount
else
    -- 需要放入令牌
    local cur_times = past_time/inteval_time -- 放几次

    cur_times=math.floor(cur_times)

    bucket_amount=current_value+cur_times*inflow__per_unit
    if (bucket_amount > capacity)
    then
        bucket_amount = capacity-amount
    end
    -- 有新投放,更新投放时间
    redis.call('set',st_key,current_time,'PX',key_expire_time)
end

res[2]=bucket_amount

-- 触发限流
if(bucket_amount<0)
then
    res[1]=1
    return res
end

-- 更新令牌桶KV
redis.call('set',KEYS[1],bucket_amount,'PX',key_expire_time)

return res

标签:令牌,--,res,Redis,lua,amount,限流,time,local
From: https://www.cnblogs.com/bruce13/p/17360016.html

相关文章

  • 自己动手实现Lua(一)
    二进制chunk:一段可以被lua解释器执行的代码就叫做chunk(写的代码)。预编译:为了获得更高的执行效率,Lua并不是直接解释执行chunk,而是先由编译器编译成内部结构(其中包含字节码等信息),然后再由虚拟机执行字节码。这种内部结构在Lua里就叫作预编译(Precompiled)chunk,由于采用了二进制格式,所......
  • redis之持久化方案,主从复制,哨兵高可用,集群原理及搭建,缓存优化
    目录redis之持久化方案,主从复制,哨兵高可用,集群原理及搭建,缓存优化昨日内容回顾今日内容详细1持久化方案1.1RDB1.2aof方案1.3混合持久化2主从复制原理和方案3哨兵高可用4集群原理及搭建4.1集群搭建4.2集群扩容4.3集群缩容5缓存优化5.1redis缓存更新策略5.2缓存穿透击......
  • redisson 分布式锁
    @RequestMapping(value="/testLock",method=RequestMethod.POST)publicBaseResponse<Boolean>testLock(@RequestBodyTestLockRequesttestLockRequest){RLockrLock=null;booleanisLocked=false;try{......
  • Redis - window下redis重启数据丢失(已解决)=========待测试
    大概场景是这样的,今天做了一些测试数据,下班了关机走人了,第二天来打开一看,redis数据丢失了都没有了,开始认为是redis自动数据过期了,但是我查看了没有设置过期时间,要么就是redis自动清理了,要么是redis重启导致数据的丢下,结果是后者。这是window下redis所有的配置文件,其中两......
  • Docker创建运行Redis并挂载
    一、拉取redis镜像1、在线状态下拉取redis镜像dockerpullredis:版本号2、离线状态下获取redis镜像将在线状态拉取额redis镜像打成tar包dockersave-oredis.tarredis:版本号sudodockerload-iredis.tar二、运行redis容器dockerrun--restart=always--log-optmax......
  • Redis - string类型
    Redis的key是String类型的,如果Value如果也是String类型,相当于把两个字符串映射起来,即key-value。这里字符串不仅仅是传统意义上的字符串,例如“helloworld”,也可以是JSON、HTML等。1、string字符串//string-----------------------------------------------------------------......
  • Ubuntu22.04 安装 mysql8,redis7,MongoDB6
     服务器的准备我的服务器是在腾讯云租的,所以服务器的apt源都是默认配好的,没配好的自行网上查找apt源配置。本文同样适用于Ubuntu22,20。Ubuntu18亦可参考。云服务器一般防火墙未开放端口访问,请自行配置,否则后续远程访问不了:mysql:3306redis:6379MongoDB:27017更新所有......
  • Python之操作redis数据库
    Python操作redis数据库步骤1、导入redis模块2、建立连接3、写入命令importredisip='xxx.xx.xx.xx'password='123456'r=redis.Redis(host=ip,password=password,port=6379,db=1)res=r.get('lrx2')print(res)#结果为:b'\xe5\x97\xafohyeah234324'#结果是......
  • Redis - 存储对象信息是用 Hash 还是 String
    日常工作中存储对象信息时,一般有两种做法,一种是用String存储,另一种是Hash 存储。既然两种数据结构都可以存储结构体信息。到底哪种更加合适呢?String和Hash占用内存的比较 首先用代码先插入10000条数据,然后用可视化工具来看看内存的占用情况。constRedis=require("......
  • Redis——cluster集群原理
    摘要在redis3.0之前,redis使用的哨兵架构,它借助sentinel工具来监控master节点的状态;如果master节点异常,则会做主从切换,将一台slave作为master。当master挂掉的时候,sentinel会选举出来一个master,选举的时候是没有办法去访问Redis的,会存在访问瞬断的情况;若是在电商网站大......