RateLimiter的使用

242 阅读2分钟

RateLimiter 是 Google Guava 库提供的基于令牌桶算法的限流工具,用于控制资源访问速率(如 API 调用、数据库查询等),防止系统过载。其核心原理、特性及用法如下:

一、核心原理:令牌桶算法

  1. 令牌生成

    • 系统以固定速率(如每秒 5 个)向桶内添加令牌,桶容量有上限(默认 1 秒的令牌量)。
    • 令牌不足时,请求需阻塞等待或直接被拒绝。
  2. 突发处理

    • 允许瞬时消耗桶内所有存储令牌(突发流量),后续请求按固定速率平滑处理。
    • 支持“预支令牌”:当请求超过当前令牌数时,可预支未来令牌,但后续请求需等待偿还预支时间。

二、核心特性

  1. 平滑突发限流(SmoothBursty

    • 默认模式,允许短时间突发请求,长期平均速率不超过设定值(如 QPS=10)。
  2. 平滑预热限流(SmoothWarmingUp

    • 系统启动时逐步增加令牌生成速率(预热期),避免冷启动流量冲击。
    • 预热期结束后,速率稳定至设定值。
  3. 非阻塞尝试

    • tryAcquire() 方法支持非阻塞获取令牌,立即返回成功/失败状态。
  4. 线程安全

    • 设计为多线程环境安全使用,无需额外同步。

三、基础用法(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 限流保护后端服务免受恶意高频请求攻击。
数据库访问控制防止数据库连接池耗尽或过载。
微服务熔断降级结合服务隔离策略,避免雪崩效应。
资源下载限速控制客户端下载带宽占用。

五、进阶配置

  1. 预热模式
// 预热期 5 秒,逐步提升至 QPS=10
RateLimiter.create(10, 5, TimeUnit.SECONDS); 
  1. 桶容量调整

    • 通过 SmoothBursty 构造参数调整桶大小(默认存 1 秒的令牌量)。

六、实现注意项

  • 无需后台线程‌:通过时间差动态计算可用令牌数(如间隔 200ms 生成 1 个令牌)。
  • 状态参数‌:桶内令牌数(storedPermits)和下次可分配时间戳(nextFreeTicketMicros)。
  • 替代方案‌:漏桶算法(如 Nginx)适用于严格平滑流量,但灵活性低于令牌桶。

⚠️ 提示:单机限流推荐 Guava,分布式场景需结合 Redis 或 Sentinel 等中间件实现集群限流。