使用 sorted set 实现令牌桶限流

时间:2025-04-10 07:09:05
-- sorted set 令牌桶的 key local key = KEYS[1]; -- 当前日期 格式为 yyyy-MM-dd local member = ARGV[1]; -- 当前日期 0 点对应的时间戳 单位为秒 local timestamp = tonumber(ARGV[2]); local exists = redis.call('exists', key); if exists == 0 then -- 创建并授权 redis.call('zadd', key, timestamp, member); redis.call('expire', key, 7 * 24 * 60 * 60); return 1; else -- 移除七天前的授权记录 本质是回收令牌 local sevenDaysAgo = timestamp - 7 * 24 * 60 * 60; redis.call('zremrangebyscore', key, '-inf', sevenDaysAgo); -- 如果队列长度少于 3 则尝试进行授权 local length = redis.call('zcard', key); if length < 3 then local count = redis.call('zcount', key, timestamp, timestamp); if (count == 0) then -- 每天不超过一次 redis.call('zadd', key, timestamp, member); redis.call('expire', key, 7 * 24 * 60 * 60); return 1; else return 0; end; else return 0; end; end;