Limitation de la fréquence des requêtes (Rate Limiting) en Java : aperçu des bibliothèques et outils
\n\nLe rate limiting (limitation de la fréquence des requêtes) est un mécanisme essentiel pour protéger les services web, les API et les microservices contre les surcharges, les attaques DDoS et les abus accidentels. En Java, il existe plusieurs bibliothèques matures implémentant différents algorithmes : du simple compteur aux systèmes distribués complexes. Dans cet article, nous examinerons trois approches principales : Guava RateLimiter, Bucket4j et Resilience4j, et discuterons de leurs applications.
\n\n1. Guava RateLimiter (simple et léger)
\n\nLa bibliothèque Google Guava fournit la classe RateLimiter, implémentant l'algorithme Token Bucket (seau de jetons) en mode monothread. Elle est idéale pour une utilisation locale dans un seul processus JVM.
Principe de fonctionnement : Le seau se remplit de jetons à une vitesse définie. Chaque requête prend un ou plusieurs jetons. Si les jetons sont insuffisants, le thread est bloqué ou la requête est rejetée.
\n\nExemple d'utilisation de Guava RateLimiter :
\n\nimport com.google.common.util.concurrent.RateLimiter;\n\npublic class GuavaRateLimiterExample {\n public static void main(String[] args) {\n // Création d'un RateLimiter à 10 requêtes par seconde\n RateLimiter rateLimiter = RateLimiter.create(10.0);\n\n // Simulation de requêtes entrantes\n for (int i = 0; i < 20; i++) {\n // tryAcquire() retourne true si un jeton est obtenu\n if (rateLimiter.tryAcquire()) {\n System.out.println("Requête " + i + " exécutée");\n } else {\n System.out.println("Requête " + i + " rejetée (limite dépassée)");\n }\n }\n }\n}\n\n\nAvantages : Dépendance minimale, simplicité, faible consommation mémoire.
\nInconvénients : Ne convient pas aux systèmes distribués (pas de synchronisation entre instances).
2. Bucket4j (Token Bucket avancé avec support Redis)
\n\nBucket4j est une bibliothèque implémentant l'algorithme Token Bucket avec des fonctionnalités avancées : support de plusieurs fournisseurs pour le stockage d'état (in-memory, Redis, Hazelcast, Infinispan), permettant son utilisation dans des scénarios distribués.
\n\nCaractéristiques clés :
\n- \n
- Support des modes greedy et interval-based. \n
- Possibilité de définir des limites sur différentes fenêtres temporelles (ex : 100 requêtes par minute + 10 requêtes par seconde). \n
- Intégration avec Jakarta EE / Spring Boot via des filtres et annotations prêts à l'emploi. \n
Exemple avec stockage 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 // Limite : 5 requêtes en 10 secondes\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("Requête " + i + " autorisée");\n } else {\n System.out.println("Requête " + i + " bloquée");\n }\n }\n }\n}\n\n\nAvantages : Configuration flexible, support distribué, haute performance.
\nInconvénients : Plus de dépendances que Guava.
3. Resilience4j RateLimiter (pour architecture microservices)
\n\nResilience4j est une bibliothèque pour la résilience, comprenant le module RateLimiter. Elle est conçue en tenant compte