RateLimiter 是 Google Guava 库提供的基于令牌桶算法的限流工具,用于控制资源访问速率(如 API 调用、数据库查询等),防止系统过载。其核心原理、特性及用法如下:
一、核心原理:令牌桶算法
-
令牌生成
- 系统以固定速率(如每秒 5 个)向桶内添加令牌,桶容量有上限(默认 1 秒的令牌量)。
- 令牌不足时,请求需阻塞等待或直接被拒绝。
-
突发处理
- 允许瞬时消耗桶内所有存储令牌(突发流量),后续请求按固定速率平滑处理。
- 支持“预支令牌”:当请求超过当前令牌数时,可预支未来令牌,但后续请求需等待偿还预支时间。
二、核心特性
-
平滑突发限流(
SmoothBursty) - 默认模式,允许短时间突发请求,长期平均速率不超过设定值(如 QPS=10)。
-
平滑预热限流(
SmoothWarmingUp) - 系统启动时逐步增加令牌生成速率(预热期),避免冷启动流量冲击。
- 预热期结束后,速率稳定至设定值。
-
非阻塞尝试
tryAcquire()方法支持非阻塞获取令牌,立即返回成功/失败状态。
-
线程安全
- 设计为多线程环境安全使用,无需额外同步。
三、基础用法(Java 示例)
1. 添加 Maven 依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
2.创建与使用
// 创建每秒允许 2 个请求的限流器
RateLimiter limiter = RateLimiter.create(2.0);
for (int i = 1; i <= 10; i++) {
// 阻塞获取令牌
limiter.acquire();
System.out.println("处理请求: " + i);
}
3.非阻塞尝试
if (limiter.tryAcquire()) { // 立即返回布尔值
// 执行业务逻辑
} else {
// 触发降级策略(如返回错误码)
}
四、适用场景
| 场景 | 作用 |
|---|---|
| API 限流 | 保护后端服务免受恶意高频请求攻击。 |
| 数据库访问控制 | 防止数据库连接池耗尽或过载。 |
| 微服务熔断降级 | 结合服务隔离策略,避免雪崩效应。 |
| 资源下载限速 | 控制客户端下载带宽占用。 |
五、进阶配置
- 预热模式
// 预热期 5 秒,逐步提升至 QPS=10
RateLimiter.create(10, 5, TimeUnit.SECONDS);
-
桶容量调整
- 通过
SmoothBursty构造参数调整桶大小(默认存 1 秒的令牌量)。
- 通过
六、实现注意项
- 无需后台线程:通过时间差动态计算可用令牌数(如间隔 200ms 生成 1 个令牌)。
- 状态参数:桶内令牌数(
storedPermits)和下次可分配时间戳(nextFreeTicketMicros)。 - 替代方案:漏桶算法(如 Nginx)适用于严格平滑流量,但灵活性低于令牌桶。
⚠️ 提示:单机限流推荐 Guava,分布式场景需结合 Redis 或 Sentinel 等中间件实现集群限流。