Limitación de frecuencia de solicitudes (Rate Limiting) en Java: revisión de bibliotecas y herramientas
\n\nRate limiting (limitación de frecuencia de solicitudes) es un mecanismo críticamente importante para proteger servicios web, API y microservicios contra sobrecargas, ataques DDoS y abuso accidental. En Java existen varias bibliotecas maduras que implementan diferentes algoritmos: desde un contador simple hasta sistemas distribuidos complejos. En este artículo, examinaremos tres enfoques principales: Guava RateLimiter, Bucket4j y Resilience4j, y discutiremos su aplicación.
\n\n1. Guava RateLimiter (simple y ligero)
\n\nLa biblioteca Google Guava proporciona la clase RateLimiter, que implementa el algoritmo Token Bucket (cubo de tokens) en modo de un solo hilo. Es ideal para uso local en un solo proceso JVM.
Principio de funcionamiento: El cubo se llena con tokens a una velocidad determinada. Cada solicitud toma uno o varios tokens. Si no hay suficientes tokens, el hilo se bloquea o la solicitud es rechazada.
\n\nEjemplo de uso de Guava RateLimiter:
\n\nimport com.google.common.util.concurrent.RateLimiter;\n\npublic class GuavaRateLimiterExample {\n public static void main(String[] args) {\n // Creamos un RateLimiter de 10 solicitudes por segundo\n RateLimiter rateLimiter = RateLimiter.create(10.0);\n\n // Simulación de solicitudes entrantes\n for (int i = 0; i < 20; i++) {\n // tryAcquire() devuelve true si se obtiene un token\n if (rateLimiter.tryAcquire()) {\n System.out.println("Solicitud " + i + " ejecutada");\n } else {\n System.out.println("Solicitud " + i + " rechazada (límite excedido)");\n }\n }\n }\n}\n\n\nVentajas: Dependencia mínima, simplicidad, bajo consumo de memoria.
\nDesventajas: No es adecuado para sistemas distribuidos (no se sincroniza entre instancias).
2. Bucket4j (Token Bucket avanzado con soporte para Redis)
\n\nBucket4j es una biblioteca que implementa el algoritmo Token Bucket con capacidades avanzadas: soporte para múltiples proveedores de almacenamiento de estado (in-memory, Redis, Hazelcast, Infinispan), lo que permite su uso en escenarios distribuidos.
\n\nCaracterísticas clave:
\n- \n
- Soporte para modos greedy e interval-based. \n
- Posibilidad de establecer límites en diferentes ventanas de tiempo (por ejemplo, 100 solicitudes por minuto + 10 solicitudes por segundo). \n
- Integración con Jakarta EE / Spring Boot a través de filtros y anotaciones predefinidos. \n
Ejemplo con almacenamiento in-memory:
\n\nimport io.github.bucket4j.Bandwidth;\nimport io.github.bucket4j.Bucket;\nimport io.github.bucket4j.Refill;\n\nimport java.time.Duration;\n\npublic class Bucket4jExample {\n public static void main(String[] args) {\n // Límite: 5 solicitudes en 10 segundos\n Bandwidth limit = Bandwidth.classic(5, Refill.intervally(5, Duration.ofSeconds(10)));\n Bucket bucket = Bucket.builder()\n .addLimit(limit)\n .build();\n\n for (int i = 0; i < 10; i++) {\n if (bucket.tryConsume(1)) {\n System.out.println("Solicitud " + i + " permitida");\n } else {\n System.out.println("Solicitud " + i + " bloqueada");\n }\n }\n }\n}\n\n\nVentajas: Configuración flexible, soporte distribuido, alto rendimiento.
\nDesventajas: Más dependencias que Guava.
3. Resilience4j RateLimiter (para arquitectura de microservicios)
\n\nResilience4j es una biblioteca para garantizar la tolerancia a fallos, que incluye el módulo RateLimiter. Está diseñada teniendo en cuenta
También en la biblioteca
Guzzle para PHP: guía completa con ejemplos
NetworkExtension Swift: guía completa con ejemplos prácticos
Internacionalización (i18n) en Go (Golang): Guía completa
Trabajo con archivos ZIP en Go (Golang): creación, lectura y extracción de archivos