【限流】基于springboot(拦截器) + redis(执行lua脚本)实现注解限流

实现了滑动窗口,固定窗口,令牌桶,漏桶四种限流算法,并且支持各种扩展和修改,源码简单易上手。
Giteehttps://gitee.com/sir-tree/rate-limiter-spring-boot-starter

一、令牌桶算法—入桶量限制

在客户端请求打过来的时候,会去桶里拿令牌,拿到就请求成功,拿不到不好意思,服务器拒绝服务。

关键点
  • 桶有多大?您定😊
  • 桶里的令牌一开始有多少?您定😊
  • 桶啥时候补充令牌?您定😊
  • 补充多少令牌?您定😊

在想好以上关键点后,我想你已经明白了。

主要步骤

请求打过来

  1. 看一下是否到补充桶的时候了,没到就到第2步,到了就补充完后再继续第2步
  2. 看一下桶里有没有令牌,有就拿走,没有就不好意思,服务器拒绝服务。
扩展:加个黑名单

请求打过来

  1. 看一下在不在黑名单,在就拒绝服务,不在,就进行第2步
  2. 看一下是否到补充桶的时候了,没到就到第2步,到了就补充完后再继续第3步
  3. 看一下桶里有没有令牌,有就拿走,没有就不好意思,加黑名单
Lua实现
-- 参数初始化
local key = KEYS[1]
local maxCapacity = tonumber(ARGV[1]) -- <= 桶有多大/桶里的令牌一开始有多少 我写成一样的了
local fill = tonumber(ARGV[2]) -- <= 补充多少令牌
local now = tonumber(ARGV[3])
local duration = tonumber(ARGV[4]) -- <= 桶啥时候补充令牌
local blackKey = key..'-black'
local blackDuration = tonumber(ARGV[5]) -- <= 黑名单多久后放开
local expire = math.ceil(now / fill) * duration

-- 黑名单
local blackValue = redis.call('get', blackKey)
if blackValue then
    return -1;
end

-- 当前值
local kValue = redis.call('get', key)

-- 第一次
if not kValue then
    -- 当前消耗#刷新时间#容量
    kValue = table.concat({
   
   '0', tostring(now + duration), tostring(maxCapacity)}, '#')
end

-- 解析
local parts = {
   
   }
for part in string.gmatch(kValue, "[^#]+") do
    table.insert(parts, part)
end

local value = tonumber(parts[1])
local refresh =<
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值