如何用 Redisson 快速给 API 网关加分布式限流:RRateLimiter 完整落地指南
【免费下载链接】redissonRedisson: Valkey & Redis Java Client and Real-Time Data Platform. Sync/Async/RxJava/Reactive API. Over 50 Valkey and Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Spring, Tomcat, Scheduler, JCache API, Hibernate, RPC, local cache..项目地址: https://gitcode.com/GitHub_Trending/re/redisson
线上 API 一遭流量尖刺,后端瞬间被打满。单机限流扛不住多实例,得靠分布式限流兜底。Redisson 是 Valkey/Redis 的 Java 客户端,内置RRateLimiter提供分布式限流能力,几行代码就能把网关入口的流量管住。本文从一个能跑的限流器讲起,再拆容易踩坑的参数,最后落到 Spring Cloud Gateway 过滤器。
3 行代码配好 RRateLimiter 跑起来
限流器不是一次性建好的对象,而是挂在某个 Redis 键上、所有节点共享同一份状态。从客户端按名字取出来即可:
// 按名字取限流器,name 决定 Redis 中的键,所有网关实例共用 RRateLimiter limiter = redisson.getRateLimiter("api:/order"); // 仅在未初始化时设置速率:整体每秒放行 100 个请求 limiter.trySetRate(RateType.OVERALL, 100, Duration.ofSeconds(1)); // 有令牌才放行,没有就立即返回 false,绝不阻塞线程 boolean pass = limiter.tryAcquire();tryAcquire()拿到令牌返回true,没拿到直接false。这里「不阻塞」是网关场景的关键——被限的请求要么快速放行,要么快速拒绝,不能卡住整个请求线程池。
这几个参数最容易踩坑
RateType 选错,配额会串味。OVERALL是全局限流,整个键下所有请求共享一份配额,适合给某个接口定总闸;PER_CLIENT则按客户端独立计数,每个 Redisson 实例各算各的,适合按调用方分别放行。给网关做接口总闸一般用OVERALL,做租户/调用方分级时才上PER_CLIENT。
trySetRate 只设一次。它只在键尚未初始化时生效,已存在就静默跳过。好处是启动时反复调用不会覆盖线上正在跑的配额;坏处是线上要改速率,得换下面说的setRate。
setRate 会清掉当前计数。它直接覆写速率并重置状态,等价于「重新开闸」。所以调速动作本身会放进来一批新令牌,别在高流量峰值那一刻随手调。
Spring Cloud Gateway 限流过滤器要点
网关侧把它做成全局过滤器最省事,每个路径一个限流键,被限的请求直接回 429:
public Mono<Void> filter(ServerWebExchange ex, GatewayFilterChain chain) { String path = ex.getRequest().getPath().value(); RRateLimiter limiter = redisson.getRateLimiter("limit:" + path); if (!limiter.tryAcquire()) { // 拿不到令牌,直接拒绝 ex.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS); // 429 return ex.getResponse().setComplete(); } return chain.filter(ex); // 放行,交给后端路由 }两个工程细节:速率配置建议单独放在初始化逻辑里,别在每个请求里反复trySetRate;键名按「路径 + 参数」拼,能把总闸和细粒度限流分开。返回体里带上Retry-After,方便客户端退避重试。
动态调速、批量与异步:调优工具箱
动态调速用setRate,流量低谷临时提速、高峰收紧都行:
// 覆写速率并重置计数,适合运维侧手动调闸 limiter.setRate(RateLimiterArgs.of(RateType.OVERALL, 200, Duration.ofSeconds(1)));批量获取:一个请求要占多个后端配额时,tryAcquire(10)一次扣 10 个令牌,避免多次往返。
异步获取:Reactor 栈里别用阻塞方法,tryAcquireAsync返回RFuture<Boolean>,直接挂到响应式链上,不占住事件循环线程。
想确认现在还剩多少配额,调availablePermits();想临时把用掉的额度还回去,用release(permits)。参数含义对照可看 RRateLimiter 源码。
限流的核心不是「限多少」,而是「被限之后怎么回」。网关侧把 429 和退避做对,后端就能在尖刺面前稳住。更多对象与服务用法见 官方文档。 🚀
【免费下载链接】redissonRedisson: Valkey & Redis Java Client and Real-Time Data Platform. Sync/Async/RxJava/Reactive API. Over 50 Valkey and Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Spring, Tomcat, Scheduler, JCache API, Hibernate, RPC, local cache..项目地址: https://gitcode.com/GitHub_Trending/re/redisson
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考