Limitation de débit en Rust : aperçu des bibliothèques et outils
La limitation de débit (rate limiting) est un mécanisme essentiel pour protéger les services web contre les surcharges, les attaques DDoS et les abus. Dans l'écosystème Rust, plusieurs bibliothèques matures sont disponibles pour implémenter la limitation de débit : des algorithmes de bas niveau aux middleware prêts à l'emploi pour les frameworks web populaires. Dans cet article, nous examinerons trois approches clés : governor (algorithme GCRA), leaky-bucket (seau percé) et l'intégration avec Actix/Axum.
1. Bibliothèque governor — algorithme GCRA
governor est la bibliothèque de limitation de débit la plus populaire en Rust, basée sur le Generic Cell Rate Algorithm (GCRA). Cet algorithme est utilisé dans les protocoles réseau et permet de configurer de manière flexible à la fois la charge de pointe et la vitesse moyenne.
Fonctionnalités clés :
- Prise en charge de plusieurs clés (IP, User-Agent, clé API)
- Burst configurable (pic de trafic)
- Fonctionnement asynchrone via
tokioouasync-std - Sécurité des threads sans verrous
Exemple de configuration d'une limite de 100 requêtes par minute avec un burst de 20 :
use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter};use std::num::NonZeroU32;use std::time::Duration;
#[tokio::main]async fn main() { // Limite : 100 requêtes par minute, burst 20 let quota = Quota::with_period(Duration::from_secs(60)) .unwrap() .allow_burst(NonZeroU32::new(20).unwrap()); let limiter = DefaultKeyedRateLimiter::::new(quota); // Vérification pour l'utilisateur "user123" match limiter.check_key("user123") { Ok(_) => println!("Requête autorisée"), Err(_) => println!("Limite dépassée, statut 429"), }} 2. Bibliothèque leaky-bucket — seau percé
L'algorithme du seau percé est implémenté dans la bibliothèque leaky-bucket. Il modélise un seau d'eau qui se remplit de requêtes et fuit à une vitesse constante. Il est adapté pour lisser les pics de charge.
Caractéristiques :
- Modèle simple : seau d'une capacité de N requêtes
- Vitesse de fuite — nombre de requêtes par seconde
- Prise en charge du nombre maximum de requêtes en attente
Exemple avec une limite de 5 requêtes par seconde et un seau de 10 :
use leaky_bucket::RateLimiter;use std::time::Duration;
#[tokio::main]async fn main() { let limiter = RateLimiter::builder() .initial(10) // nombre initial de jetons .max(10) // taille maximale du seau .interval(Duration::from_millis(200)) // remplissage toutes les 200 ms .build(); // Tentative d'obtention d'un jeton if limiter.try_acquire().is_ok() { println!("Requête traitée"); } else { println!("Seau vide, refus"); }}3. Middleware pour frameworks web
Les middleware prêts à l'emploi simplifient considérablement l'intégration de la limitation de débit dans les serveurs web basés sur Actix et Axum.
Actix + governor
use actix_web::{web, App, HttpServer, HttpRequest, HttpResponse, middleware::from_fn};use governor::{DefaultKeyedRateLimiter, Quota};use std::num::NonZeroU32;use std::time::Duration;
async fn rate_limit_middleware( req: HttpRequest, limiter: web::Data<DefaultKeyedRateLimiter<String>>,) -> Result<HttpResponse, actix_web::Error> { let client_ip = req.peer_addr() .map(|addr| addr.to_string()) .unwrap_or_default(); match limiter.check_key(&client_ip) { Ok(_) => Ok(HttpResponse::Ok().body("OK")), Err(_) => Ok(HttpResponse::TooManyRequests().body("Too Many Requests")), }} Aussi dans la bibliothèque
GraphQL Java : Guide complet de la bibliothèque pour créer des API en Java
Travailler avec les archives ZIP en C# (.NET) : guide complet
Génération de PDF en Go (Golang) : bibliothèques et exemples
Frameworks CLI pour TypeScript : aperçu complet et exemples d'utilisation