-- Lua script for Redis to implement sliding window rate limiting local key = KEYS[1] -- Redis key for the sorted set local limit = tonumber(ARGV[1]) -- Request limit for the window local windowSize = tonumber(ARGV[2]) -- Window size in seconds local currentTime = tonumber(ARGV[3]) -- Current timestamp in milliseconds local clearBefore = currentTime - windowSize * 1000-- Calculate the timestamp to clear
-- Remove timestamps outside the current window redis.call('ZREMRANGEBYSCORE', key, 0, clearBefore)
-- Add the current request timestamp to the sorted set with the current time as the score redis.call('ZADD', key, currentTime, currentTime)
-- Count the number of requests in the current window local count = redis.call('ZCOUNT', key, clearBefore, currentTime)
-- Set the sorted set to expire to avoid it growing indefinitely redis.call('EXPIRE', key, windowSize)
-- Return whether the current request is allowed (1) or rate-limited (0) if count <= limit then return1 else return0 end
-- 漏斗名 对应每个请求源 local funnel_key = KEYS[1] -- 漏斗容量 最多多少请求 local capacity = tonumber(ARGV[1]) -- 漏斗流速 每毫秒能流出多少请求 local leak_rate = tonumber(ARGV[2]) -- 当前时间戳 local current_time = tonumber(ARGV[3])
-- 获取上一次流出的时间和上一次的水位 local funnel = redis.call('HMGET', funnel_key, 'last_time', 'water_height') local last_time = tonumber(funnel[1]) local water_height = tonumber(funnel[2])
-- 如果是第一次请求那么就初始化 if last_time == nilthen last_time = current_time water_height = 0 end
-- 计算时间差 local delta_time = current_time - last_time -- 根据时间差计算上一次到现在能流出多少请求出来 local leaked_volume = delta_time * leak_rate water_height = math.max(0, water_height - leaked_volume) -- Ensure water height does not go negative
-- 更新上一次流出时间 last_time = current_time
-- 更新桶 在这里是默认一个请求一个请求进入的 if water_height < capacity then water_height = water_height + 1 -- 再次检查是否超出容量 这是当我们每次进入的请求如果不是1的情况下 if water_height <= capacity then -- 更新hash redis.call('HMSET', funnel_key, 'last_time', last_time, 'water_height', water_height) return1 end end
local key = KEYS[1] local intervalPerTokens = tonumber(ARGV[1]) local curTime = tonumber(ARGV[2]) local initTokens = tonumber(ARGV[3]) local bucketMaxTokens = tonumber(ARGV[4]) local resetBucketInterval = tonumber(ARGV[5])
local bucket = redis.call('hgetall', key) local currentTokens