RateLimiter代码中写限流

2025-2-22 diaba 分布式

RateLimiter 是 Guava 工具包中用于控制操作频率的工具,它基于令牌桶算法实现,能够限制代码的执行速率。以下是 RateLimiter 的使用方法和一些高级特性:

基本使用

RateLimiter 通过 RateLimiter.create(double permitsPerSecond) 方法创建,其中 permitsPerSecond 表示每秒允许的令牌数量。例如,创建一个每秒允许 2 个请求的 RateLimiter

RateLimiter rateLimiter = RateLimiter.create(2.0);

在需要限制频率的操作前,调用 acquire() 方法获取令牌:


rateLimiter.acquire(); // 阻塞等待获取令牌



如果需要获取多个令牌,可以指定数量:


rateLimiter.acquire(3); // 获取3个令牌

避免无限等待



acquire() 方法会阻塞当前线程直到获取到令牌,可能导致线程无限期等待。为了避免这种情况,可以使用 tryAcquire() 方法,它允许设置超时时间:
if (rateLimiter.tryAcquire(2, TimeUnit.SECONDS)) {
    // 在2秒内获取到令牌,执行操作
} else {
    // 超时未获取到令牌,执行其他逻辑
}



高级特性


SmoothBursty 与 SmoothWarmingUp

RateLimiter 提供了两种模式

1.SmoothBursty:允许在短时间内处理大量请求,然后速率逐渐下降到稳定状态

2.SmoothWarmingUp:在启动时逐渐增加发放令牌的速率,直到达到稳定状态

例如,创建一个预热时间为 10 秒、每秒 5 个令牌的 RateLimiter

RateLimiter warmingUpLimiter = RateLimiter.create(5.0, 10, TimeUnit.SECONDS);

实际应用场景

RateLimiter 常用于控制网络请求、数据库操作等的频率,防止系统过载。例如,在 Web 服务中限制接口调用频率



RateLimiter rateLimiter = RateLimiter.create(1.0); // 每秒1个请求

public void handleRequest(int requestId) {
    if (rateLimiter.tryAcquire()) {
        System.out.println("处理请求: " + requestId);
        // 处理请求
    } else {
        System.out.println("请求 " + requestId + " 被限流");
    }
}


通过合理使用 RateLimiter,可以有效控制操作频率,提升系统的稳定性和响应性。





标签: 限流

发表评论:

Powered by emlog 京ICP备15045175号-1 Copyright © 2022