Limitation de débit en Rust : bibliothèques governor, leaky-bucket et middleware pour serveurs web

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

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 tokio ou async-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")), }}

Recommendations