All Downloads are FREE. Search and download functionalities are using the official Maven repository.

script.TimeSlidingWindowRateLimiter.lua Maven / Gradle / Ivy

The newest version!
-- 时间滑动窗口限流器
local size_key      = KEYS[1]        -- 时间窗口大小(秒)的 key
local limit_key     = KEYS[2]        -- 时间窗口内允许的最大请求数的 key
local window_key    = KEYS[3]        -- 时间窗口的 key
local expires_key   = KEYS[4]        -- 到期秒数的 key
local blacklist_key = KEYS[5]        -- 黑名单的 key

local expires = tonumber(redis.call("GET", expires_key))
if expires == nil then
    expires = 3600                  -- 到期时间默认30分钟
    redis.call("SETEX", expires_key, expires, expires)
else
    redis.call("EXPIRE", expires_key, expires)
end

local size = tonumber(redis.call("GET", size_key))
if size == nil then
    size = 60                       -- 时间窗口大小默认1分钟
    redis.call("SETEX", size_key, expires, size)
else
    redis.call("EXPIRE", size_key, expires)
end

local limit = tonumber(redis.call("GET", limit_key))
if limit == nil then
    limit = 2000                    -- 默认单位时间内最多处理2000条请求
    redis.call("SETEX", limit_key, expires, limit)
else
    redis.call("EXPIRE", limit_key, expires)
end

-- 获取当前时间(秒)
local now = redis.call("TIME")
local current_time = tonumber(now[1])

-- 删除超出时间的时间戳
redis.call("ZREMRANGEBYSCORE", window_key, 0, current_time - size)

-- 获取当前时间窗口内的请求数量
local request_count = redis.call("ZCARD", window_key)

if request_count < limit then
    -- 将当前请求的时间戳添加到有序集合中
    redis.call("ZADD", window_key, current_time, current_time)
    redis.call("EXPIRE", window_key, expires)
    return 1 -- 允许请求
else
    redis.call("EXPIRE", window_key, expires)
    return 0 -- 拒绝请求
end




© 2015 - 2025 Weber Informatics LLC | Privacy Policy