1793 字
约 5 分钟
1
Redis 限流入门

Redis 限流入门

1. 一句话简介

Redis 限流是借助 Redis 作为集中式存储,面向多实例分布式部署场景实现的接口访问频率控制方案。核心做法是:用 Redis 的 Sorted Set(有序集合)记录每次请求的时间戳,配合 Lua 脚本在 Redis 服务端原子地执行「清除过期记录 → 计数 → 判断阈值 → 写入计时」这一完整流程,从而在单个时间窗口内精确限制某接口的最大访问次数。

demo-ratelimit-redis 中,该能力被封装为自定义注解 @RateLimiter + AOP 切面:业务方法只需标注 @RateLimiter(max = 5),切面即拦截请求、按「类名.方法名:客户端IP」构造 Redis Key、执行 limit.lua 脚本,返回 0 表示已达上限并抛出异常,由全局异常处理器转成友好的「手速太快了,慢点儿吧~」提示。它解决的核心问题是:在应用多节点部署时,单机限流(如 Guava RateLimiter)无法统一全局额度,需要一个跨实例共享计数器的分布式限流方案,同时要保证高并发下判断与写入的原子性。

2. 什么时候使用

  • 适用场景
    • 分布式多实例部署:应用以集群方式运行,需要所有实例共享同一份限流额度,达到全局一致的限制效果,而非各实例各自为政。
    • 按接口粒度动态限流:希望用注解声明式地给单个接口指定「时间窗口内最大请求数」,随改随生效,且不影响未标注的接口。
    • 按业务维度/按用户维度隔离:例如按客户端 IP、按用户 ID、按自定义 Key(订单号、接口分组)分别限流,使单个用户或单个维度被限制时不拖累他人,项目切面正是按 IP 隔离。
    • 需要精确计数与原子性:限流判断和写入必须是原子的(用 Lua 脚本实现),避免高并发下「先判断后写入」产生的超发竞态。
    • 项目本身已引入 Redis:基础设施已具备,无需再引入重型组件即可快速落地。
  • 不适用 / 需谨慎
    • 单机部署且追求极低开销:单实例场景用 Guava RateLimiter 等进程内限流即可,引入 Redis 限流会带来一次额外的网络请求(RTT)和运维依赖。
    • 无外部依赖的轻量项目:限流需要 Redis 服务可用,Redis 挂掉或不可达时,限流判定会失败或异常,需考虑降级策略。
    • 需要「平滑」的突发平滑:本模块采用滑动窗口精确计数,不具备令牌桶式的匀速排空能力——若希望「限到 N 但又允许瞬时突发并平滑补偿」,滑动窗口/固定窗口都不合适。
    • 追求高精度吞吐:极端高 QPS 场景下,每次请求多一次 Redis RTT 会带来额外延迟,若对性能极其敏感需评估(可改用令牌桶原子脚本或网关层限流)。
    • 配置灵活性要求高:简单注解式限流难以表达复杂规则(多级限流、熔断、热点细粒度统计),复杂治理需求更适合 Sentinel 等重方案。

3. 常见业务场景

  • 接口防刷 / 反爬:对登录接口、短信验证码接口、查询接口加上 @RateLimiter(max = 5),限制同一 IP 在一分钟内的访问次数。模块中的 test1 接口即演示此场景——快速刷新超过 5 次即被拦截并返回「手速太快了,慢点儿吧~」,test2 作为对照组不受影响,验证限流只作用于被注解保护的接口。
  • 可共享额度的接口组限流:用自定义 Key 让多个接口共享同一个限流计数器。模块 test3 演示 @RateLimiter(value = 2, key = "测试自定义key"),业务中可给同一产品线、同一用户分组的所有接口打上同一 Key,实现一组接口合计限 N 次/分钟。
  • 按用户维度的 VIP/免费额度管理:把注解 Key 改为「userId」而非默认 IP,实现免费用户接口 10 次/分钟、VIP 用户 100 次/分钟的分级配额,不同用户额度互不占用。
  • 秒杀 / 抢购活动的后端风控前置:在分布式部署下用 Redis 限流保护下单、扣库存等核心接口,通过 AOP 切面在所有实例上统一生效,防止瞬间流量压垮数据库,并配合 Redis 的集中计数器保证各实例额度一致。
  • 第三方 API 调用频率保护:作为网关或服务层保护对外调用的第三方接口(供应商 API 常限制 QPS),用 Redis 限流限制本系统对下游的调用速率,避免触发对方的封禁。

4. 同类技术对比

方案 分布式能力 限流算法/精度 原子性保障 学习/接入成本 适用规模
Redis + Lua 滑动窗口(本模块) 强,多实例共享 精确计数,滑动窗口无边界突发,按 IP/维度隔离 强,Lua 脚本服务端原子执行 低,一个注解 + AOP,需 Redis 中小型分布式应用
Guava RateLimiter(令牌桶) 无,仅单机 平滑限流,可均匀处理突发 进程内线程安全 极低,仅引入 jar 单机 / 网关单实例
Nginx limit_req 网关限流 需自行保证共享(通常加 Redis/外部模块) 漏桶式固定速率,粒度较粗,按 IP 为主 由网关保证 低,配置即用 接入层统一限流,规模大
Sentinel(阿里开源) 丰富:滑动窗口、令牌桶、熔断降级、热点参数 高,功能多、学习成本高、引入较重 大型复杂系统、微服务治理

选型建议:刚起步、已有 Redis、希望用最简单方式给接口加分布式限流,首选 Redis + Lua 滑动窗口方案(本模块即为模板),代码量小且原子性可靠。若只需单机保护或平滑排空突发流量,直接用 Guava RateLimiter 更省一次网络开销。若限流对象是「对外统一入口」而非业务接口,用 Nginx 网关限流最高效、性能最好。若系统已经引入微服务治理并需要限流之外的熔断、降级、热点统计等完整能力,选择 Sentinel;承受不起其学习与运维成本前,Redis 限流已足够。

Redis 限流入门
http://clxhxhhr.top/posts/501/
作者
clxstart
发布于
2026-09-07
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。