实现了滑动窗口,固定窗口,令牌桶,漏桶四种限流算法,并且支持各种扩展和修改,源码简单易上手。
Gitee:https://gitee.com/sir-tree/rate-limiter-spring-boot-starter
一、令牌桶算法—入桶量限制
在客户端请求打过来的时候,会去桶里拿令牌,拿到就请求成功,拿不到不好意思,服务器拒绝服务。
关键点
- 桶有多大?您定😊
- 桶里的令牌一开始有多少?您定😊
- 桶啥时候补充令牌?您定😊
- 补充多少令牌?您定😊
在想好以上关键点后,我想你已经明白了。
主要步骤
请求打过来
- 看一下是否到补充桶的时候了,没到就到第2步,到了就补充完后再继续第2步
- 看一下桶里有没有令牌,有就拿走,没有就不好意思,服务器拒绝服务。
扩展:加个黑名单
请求打过来
- 看一下在不在黑名单,在就拒绝服务,不在,就进行第2步
- 看一下是否到补充桶的时候了,没到就到第2步,到了就补充完后再继续第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 =<

最低0.47元/天 解锁文章
10万+

被折叠的 条评论
为什么被折叠?



