使用 sorted set 实现令牌桶限流

业务场景为限制消息发送,要求每天不超过一次,每七天不超过三次

Redission 的 RRateLimiter 虽然功能完备且支持自定义限流配置,但是每个限流器都需要维护三个 key,并且 lua 脚本中的判断逻辑较为复杂。

见:Redisson 分布式限流器 RRateLimiter 的使用及原理

此外,本业务场景每次固定只需要获取一个令牌,且时间等限流参数固定,因此完全可以通过一个 sorted set 实现令牌桶限流。

对应 lua 脚本:

lua 复制代码
-- 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;
相关推荐
霸道流氓气质1 小时前
分布式系统设计:技术解析与实践
分布式
ACP广源盛139246256734 小时前
蚂蚁百灵 Ling‑3.0‑flash 开源 + 昇腾 0‑Day 原生适配@ACP#GSV9001E 在国产算力矩阵中的机会与落地场景
大数据·人工智能·分布式·单片机·嵌入式硬件
汽车仪器仪表相关领域8 小时前
KRYPTON坚固型IP67 EtherCAT总线数据采集模块:工业级分布式采集方案
分布式·功能测试·汽车·压力测试·可用性测试
霸道流氓气质10 小时前
Java中信号量(Semaphore):从本地到分布式
java·开发语言·分布式
naierfengdian11 小时前
分布式风电助力乡村能源转型的技术路径
分布式·能源
霸道流氓气质12 小时前
RedLock:Redis 分布式锁的高可用方案
数据库·redis·分布式
hhzz12 小时前
《深度学习框架PyTorch入门与实践》系列:09-分布式与并行训练之DataParallel、DDP与Horovod
pytorch·分布式·深度学习
城管不管1 天前
重生——第九次面试2026.8.13某车一面
分布式·ai·面试·职场和发展·rabbitmq
ly76891 天前
分布式一致性算法详解:从 2PC、3PC 到 Paxos、Raft、ZAB
分布式·算法
珠***格1 天前
通信链路全打通:西格电力四可装置的 4G/5G + 加密认证技术详解
大数据·数据库·分布式·5g·架构·能源