Java中的速率限制:用于控制请求的库和工具(Bucket4j, Resilience4j)

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java中的请求频率限制(Rate Limiting):库和工具概述



速率限制(Rate limiting)是保护Web服务、API和微服务免受过载、DDoS攻击和意外滥用的关键机制。在Java中,有几种成熟的库实现了不同的算法:从简单的计数器到复杂的分布式系统。在本文中,我们将探讨三种主要方法:Guava RateLimiter、Bucket4j 和 Resilience4j,并讨论它们的应用。



1. Guava RateLimiter(简单轻量级)



Google Guava 库提供了 RateLimiter 类,在单线程模式下实现了 令牌桶(Token Bucket)算法。它非常适合在单个JVM进程中进行本地使用。



工作原理: 桶以特定速率填充令牌。每个请求消耗一个或多个令牌。如果令牌不足,线程将被阻塞或请求被拒绝。



Guava RateLimiter 使用示例:



import com.google.common.util.concurrent.RateLimiter;

public class GuavaRateLimiterExample { public static void main(String[] args) { // 创建一个每秒10个请求的RateLimiter RateLimiter rateLimiter = RateLimiter.create(10.0);

// 模拟传入请求 for (int i = 0; i < 20; i++) { // tryAcquire() 如果获取到令牌则返回true if (rateLimiter.tryAcquire()) { System.out.println("请求 " + i + " 已执行"); } else { System.out.println("请求 " + i + " 被拒绝(超出限制)"); } } }}


优点: 依赖最小,简单,内存占用低。
缺点: 不适用于分布式系统(无法在实例之间同步)。



2. Bucket4j(高级令牌桶,支持Redis)



Bucket4j 是一个实现令牌桶算法的库,具有扩展功能:支持多种状态存储提供程序(内存、Redis、Hazelcast、Infinispan),使其可用于分布式场景。



主要特点:

  • 支持 贪婪 和 基于间隔 模式。
  • 能够为不同的时间窗口设置限制(例如,每分钟100个请求 + 每秒10个请求)。
  • 通过现成的过滤器和注解与 Jakarta EE / Spring Boot 集成。


使用内存存储的示例:



import io.github.bucket4j.Bandwidth;import io.github.bucket4j.Bucket;import io.github.bucket4j.Refill;

import java.time.Duration;

public class Bucket4jExample { public static void main(String[] args) { // 限制:10秒内5个请求 Bandwidth limit = Bandwidth.classic(5, Refill.intervally(5, Duration.ofSeconds(10))); Bucket bucket = Bucket.builder() .addLimit(limit) .build();

for (int i = 0; i < 10; i++) { if (bucket.tryConsume(1)) { System.out.println("请求 " + i + " 已允许"); } else { System.out.println("请求 " + i + " 已阻止"); } } }}


优点: 灵活配置,分布式支持,高性能。
缺点: 比Guava有更多依赖。



3. Resilience4j RateLimiter(用于微服务架构)



Resilience4j 是一个用于实现容错能力的库,其中包含 RateLimiter 模块。它的设计考虑到了

推荐