Rate limiting in Rust: Überblick über Bibliotheken und Werkzeuge
Rate limiting (Anfragefrequenzbegrenzung) ist ein kritisch wichtiger Mechanismus zum Schutz von Webdiensten vor Überlastung, DDoS-Angriffen und Missbrauch. Im Rust-Ökosystem stehen mehrere ausgereifte Bibliotheken zur Implementierung von Rate limiting zur Verfügung: von Low-Level-Algorithmen bis hin zu fertigen Middleware für gängige Web-Frameworks. In diesem Artikel betrachten wir drei Schlüsselansätze: governor (GCRA-Algorithmus), leaky-bucket (Leaky Bucket) und die Integration mit Actix/Axum.
1. Bibliothek governor – GCRA-Algorithmus
governor ist die beliebteste Rate-Limiting-Bibliothek in Rust, basierend auf dem Generic Cell Rate Algorithm (GCRA). Dieser Algorithmus wird in Netzwerkprotokollen verwendet und ermöglicht eine flexible Konfiguration sowohl der Spitzenlast als auch der Durchschnittsrate.
Wichtige Funktionen:
- Unterstützung mehrerer Schlüssel (IP, User-Agent, API-Key)
- Konfigurierbarer Burst (Verkehrsspitze)
- Asynchrone Arbeit über
tokiooderasync-std - Threadsicherheit ohne Sperren
Beispiel für die Konfiguration eines Limits von 100 Anfragen pro Minute mit einem Burst von 20:
use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter};use std::num::NonZeroU32;use std::time::Duration;
#[tokio::main]async fn main() { // Limit: 100 Anfragen pro Minute, Burst 20 let quota = Quota::with_period(Duration::from_secs(60)) .unwrap() .allow_burst(NonZeroU32::new(20).unwrap()); let limiter = DefaultKeyedRateLimiter::<String>::new(quota); // Prüfung für Benutzer "user123" match limiter.check_key("user123") { Ok(_) => println!("Anfrage erlaubt"), Err(_) => println!("Limit überschritten, Status 429"), }}2. Bibliothek leaky-bucket – Leaky Bucket
Der Leaky-Bucket-Algorithmus ist in der Bibliothek leaky-bucket implementiert. Er modelliert einen Wassereimer, der sich mit Anfragen füllt und mit konstanter Geschwindigkeit ausläuft. Geeignet zum Glätten von Lastspitzen.
Eigenschaften:
- Einfaches Modell: Eimer mit einer Kapazität von N Anfragen
- Leckrate – Anzahl der Anfragen pro Sekunde
- Unterstützung eines Maximums an wartenden Anfragen
Beispiel mit einem Limit von 5 Anfragen pro Sekunde und einem Eimer für 10:
use leaky_bucket::RateLimiter;use std::time::Duration;
#[tokio::main]async fn main() { let limiter = RateLimiter::builder() .initial(10) // anfängliche Tokenanzahl .max(10) // maximale Eimergröße .interval(Duration::from_millis(200)) // Auffüllung alle 200 ms .build(); // Versuch, einen Token zu erhalten if limiter.try_acquire().is_ok() { println!("Anfrage verarbeitet"); } else { println!("Eimer leer, Ablehnung"); }}3. Middleware für Web-Frameworks
Fertige Middleware vereinfacht die Integration von Rate limiting in Webserver mit Actix und Axum erheblich.
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")), }} Auch in der Bibliothek
Konfiguration von Node.js-Anwendungen: Beste Bibliotheken und Praktiken
Poco C++: Das umfassende Tutorial mit Praxisbeispielen
Arbeiten mit Daten in C++: Überblick über Bibliotheken zur Zeitmanipulation
Aufgabenplaner für Node.js: node-schedule und node-cron