Bucket4j para Java: Guía completa de Rate Limiting
En el desarrollo de software moderno, especialmente al crear servicios web y APIs de alta concurrencia, es fundamental controlar la intensidad de las solicitudes entrantes. Sin este control, un usuario malintencionado o un error en el sistema podría provocar una denegación de servicio (DoS) para el resto de los clientes. Aquí es donde entra en juego el concepto de Rate Limiting (limitación de velocidad), y la librería Bucket4j es una de las herramientas más potentes y flexibles para implementarlo en la plataforma Java.
Bucket4j es una librería para Java, thread-safe y basada en el algoritmo Token Bucket (cubo de fichas). Permite a los desarrolladores limitar de forma fácil y eficiente la frecuencia de operaciones: número de peticiones HTTP a una API, llamadas a base de datos, envío de mensajes, etc. A diferencia de los contadores simples, el algoritmo Token Bucket suaviza la carga, permitiendo picos breves de tráfico mientras respeta estrictamente la velocidad media a largo plazo. Esto lo convierte en la opción ideal para la mayoría de los escenarios reales.
¿Por qué usar Bucket4j? Primero, protege tu backend contra sobrecargas y ataques. Segundo, te permite implementar planes de suscripción por niveles (usuarios premium con más solicitudes por segundo). Tercero, la librería ofrece una API completa para ajustes finos, incluyendo diferentes estrategias de regeneración de tokens, soporte para sistemas distribuidos con Redis o Hazelcast, e integración con frameworks populares como Spring Boot. Bucket4j no es un simple "placeholder", sino una herramienta de producción completa.
Instalación
Bucket4j se distribuye a través del repositorio central de Maven (Maven Central). Para añadir la librería a tu proyecto, debes agregar la dependencia en el archivo pom.xml (para Maven) o build.gradle (para Gradle).
Maven (pom.xml):
<dependency>
<groupId>com.github.vladimir-bukhtoyarov</groupId>
<artifactId>bucket4j-core</artifactId>
<version>8.7.0</version>
</dependency>
Gradle (build.gradle):
implementation 'com.github.vladimir-bukhtoyarov:bucket4j-core:8.7.0'
Importante: La versión 8.x requiere Java 11 o superior. Si usas Java 8, necesitarás la versión 7.x. Para trabajar con cachés distribuidas (Redis, Hazelcast), debes añadir los módulos correspondientes, como bucket4j-redis.
Inicio rápido: Ejemplo mínimo funcional
Vamos a crear un limitador simple que permita un máximo de 10 operaciones por segundo.
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Refill;
import java.time.Duration;
public class QuickStartExample {
public static void main(String[] args) {
// 1. Configuración: 10 tokens, se reponen 10 tokens cada segundo
Bandwidth limit = Bandwidth.classic(10, Refill.greedy(10, Duration.ofSeconds(1)));
// 2. Creación del cubo
Bucket bucket = Bucket.builder()
.addLimit(limit)
.build();
// 3. Simulación de solicitudes
for (int i = 1; i <= 15; i++) {
boolean consumed = bucket.tryConsume(1);
if (consumed) {
System.out.println("Solicitud " + i + ": Exitosa (token obtenido)");
} else {
System.out.println("Solicitud " + i + ": RECHAZADA (límite excedido)");
}
}
}
}
Este código crea un cubo con 10 tokens. Cada segundo se añaden 10 tokens nuevos (relleno greedy: los tokens se agregan de forma continua, no en bloque al final del intervalo). Las primeras 10 solicitudes se ejecutarán de inmediato
También en la biblioteca
Envío de SMS en Java: resumen de bibliotecas API (Twilio, Nexmo, pasarelas SMS)
Geolocalización y mapas en TypeScript: bibliotecas y ejemplos prácticos
Tokio para Rust: guía completa con ejemplos