Rate Limiting en Kotlin : bibliothèques, stratégies et exemples pratiques
\n\nLe rate limiting (limitation du débit des requêtes) est un mécanisme essentiel pour protéger les API, les microservices et les applications web contre les charges excessives, les attaques DDoS et les pics de trafic soudains. Dans l'écosystème Kotlin, fonctionnant sur la JVM, il existe plusieurs bibliothèques matures qui permettent de mettre en œuvre cette logique de manière flexible. Dans cet article, nous allons analyser trois approches et outils principaux : Bucket4j, Resilience4j et le RateLimiter intégré de Guava.
\n\n1. Bucket4j — implémentation avancée du Token Bucket
\n\nBucket4j est une bibliothèque Java, parfaitement compatible avec Kotlin. Elle implémente l'algorithme Token Bucket (seau de jetons) et prend en charge la limitation à la fois locale et distribuée (via Redis, Hazelcast, Infinispan).
\n\nFonctionnalités clés :
\n- \n
- Configuration du nombre de jetons et de leur vitesse de régénération. \n
- Prise en charge des « bursts » (pics temporaires) grâce à l'accumulation de jetons. \n
- Fonctionnement en environnement multithread sans blocage. \n
- Intégration avec Spring Boot via le starter
bucket4j-spring-boot-starter. \n
Exemple simple de rate limiter en Kotlin :
\nimport io.github.bucket4j.Bandwidth\nimport io.github.bucket4j.Bucket\nimport io.github.bucket4j.Refill\nimport java.time.Duration\n\nfun main() {\n // 10 requêtes par minute, avec possibilité d'accumuler jusqu'à 20 jetons\n val limit = Bandwidth.classic(20, Refill.greedy(10, Duration.ofMinutes(1)))\n val bucket = Bucket.builder()\n .addLimit(limit)\n .build()\n\n // Vérifier la disponibilité d'un jeton\n if (bucket.tryConsume(1)) {\n println("✅ Requête autorisée")\n } else {\n println("❌ Limite dépassée, réessayez plus tard")\n }\n}\n\nPour un scénario distribué (par exemple, plusieurs instances d'un microservice), utilisez Bucket4j avec Redis :
\nimport io.github.bucket4j.distributed.proxy.ProxyManager\nimport io.github.bucket4j.redis.lettuce.Bucket4jLettuce\nimport io.lettuce.core.RedisClient\n\nval redisClient = RedisClient.create("redis://localhost:6379")\nval proxyManager: ProxyManager<String> = Bucket4jLettuce\n .builder(redisClient)\n .build()\n\nval bucket = proxyManager.builder()\n .build("user:123", Bucket4jConfiguration(\n Bandwidth.classic(100, Refill.intervally(100, Duration.ofMinutes(1)))\n ))\n\n\n2. Resilience4j — RateLimiter comme composant du Circuit Breaker
\n\nResilience4j est une bibliothèque de résilience populaire pour Java/Kotlin, incluant non seulement un rate limiter, mais aussi un circuit breaker, retry, bulkhead. Son module RateLimiter fonctionne sur la base de l'algorithme Sliding Window (fenêtre glissante).
Caractéristiques :
\n- \n
- Intégration facile avec les coroutines Kotlin via les fonctions
suspend. \n - Configuration de la période de la fenêtre et de la limite de requêtes. \n
- Gestion flexible des échecs : retour d'exception, fallback ou attente. \n
Exemple avec les coroutines :
\nimport io.github.resilience4j.ratelimiter.RateLimiter\nimport io.github.resilience4j.ratelimiter.RateLimiterConfig\nimport io.github.resilience4j.kotlin.ratelimiter.awaitRateLimiter\nimport java.time.Duration\nimport kotlinx.coroutines.runBlocking\n\nval config = RateLimiterConfig.custom()\n .limitForPeriod(10) // 10 requêtes\n .limitRefreshPeriod(Duration.ofSeconds(1)) // par seconde\n .timeoutDuration(Duration.ofMillis(500)) // délai d'attente\n .build()\n\nval rateLimiter = RateLimiter.of("api-limiter", config)\n\nsuspend fun fetchData(): String {\n return awaitRateLimiter(rateLimiter) {\n // Votre appel API\n "Données reçues"\n }\n}\n\nfun main() = runBlocking {\n val result = fetchData()\n p Aussi dans la bibliothèque
Générateur de QR codes en Rust : bibliothèque qr_code
validator — Validation des données en Rust
Travailler avec YAML en TypeScript : parsing, génération et validation de données