Rate Limiting in Rust: Bibliotheken zur Begrenzung der Anfragefrequenz

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Rate Limiting in Rust: Effizientes Lastmanagement

\n\n

Rate Limiting (Begrenzung der Anfragefrequenz) ist ein Schlüsselmechanismus zum Schutz und zur Optimierung von Webdiensten, APIs und Netzwerkanwendungen. Im Rust-Ökosystem gibt es mehrere ausgereifte Bibliotheken, die verschiedene Algorithmen implementieren: vom klassischen Token-Bucket bis hin zu modernen adaptiven Methoden. In diesem Artikel analysieren wir die drei wichtigsten Bibliotheken: governor, leaky-bucket und ratelimit, mit Codebeispielen und Empfehlungen zur Auswahl.

\n\n

1. Die Bibliothek governor – der Goldstandard

\n\n

governor ist die beliebteste und flexibelste Bibliothek für Rate Limiting. Sie implementiert den Generic Cell Rate Algorithm (GCRA), der eine präzise Einhaltung der Limits mit minimaler Verzögerung gewährleistet. Unterstützt synchrone und asynchrone Modi sowie Middleware für Actix-web, Axum und Rocket.

\n\n

Basisbeispiel mit governor

\n
use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter};\nuse std::num::NonZeroU32;\nuse std::time::Duration;\n\nfn main() {\n    // Erlaubt 5 Anfragen pro Sekunde\n    let quota = Quota::per_second(NonZeroU32::new(5).unwrap());\n    let limiter = RateLimiter::direct(quota);\n\n    for i in 0..10 {\n        match limiter.check() {\n            Ok(_) => println!("Anfrage {} erlaubt", i),\n            Err(_) => println!("Anfrage {} abgelehnt (Rate Limit)", i),\n        }\n        std::thread::sleep(Duration::from_millis(100));\n    }\n}
\n\n

Asynchrone Variante mit Warten

\n
use governor::{Quota, RateLimiter};\nuse std::num::NonZeroU32;\nuse tokio::time::{sleep, Duration};\n\n#[tokio::main]\nasync fn main() {\n    let limiter = RateLimiter::direct(Quota::per_second(\n        NonZeroU32::new(2).unwrap(),\n    ));\n\n    for i in 0..5 {\n        limiter.until_ready().await;\n        println!("Anfrage {} verarbeitet", i);\n        sleep(Duration::from_millis(300)).await;\n    }\n}
\n\n

Wichtige Funktionen von governor:

\n
    \n
  • Unterstützung von schlüsselbasierten Limits (pro-IP, pro-User) über KeyedRateLimiter
  • \n
  • Integration mit tower Middleware für HTTP-Server
  • \n
  • Anpassbare Strategien: Warten, Ablehnen, adaptive Verlangsamung
  • \n
  • Minimaler Speicherverbrauch (ein atomarer Zähler pro Limiter)
  • \n
\n\n

2. Die Bibliothek leaky-bucket – Einfachheit und Zuverlässigkeit

\n\n

leaky-bucket implementiert den klassischen „Leaky-Bucket“-Algorithmus. Er ist ideal zum Glätten von Lastspitzen, wenn ein gleichmäßiger Anfragefluss gewährleistet werden muss. Die Bibliothek ist leichtgewichtig und benötigt keine externen Abhängigkeiten.

\n\n

Beispiel mit leaky-bucket

\n
use leaky_bucket::RateLimiter;\nuse std::time::Duration;\n\n#[tokio::main]\nasync fn main() {\n    let limiter = RateLimiter::builder()\n        .initial(10)        // anfänglicher Token-Vorrat\n        .interval(Duration::from_secs(1))  // Auffüllintervall\n        .refill(5)          // wie viele Token pro Intervall hinzugefügt werden\n        .max(20)            // maximale Anzahl an Token\n        .build();\n\n    for i in 0..15 {\n        limiter.acquire_one().await;\n        println!("Anfrage {} ausgeführt", i);\n    }\n}
\n\n

Besonderheiten von leaky-bucket:

\n
    \n
  • Unterstützung von asynchroner und blockierender API
  • \n
  • Möglichkeit zur Konfiguration eines „Burst“-Modus (kurzzeitige Spitzen)
  • \n
  • Automatische Freigabe von Token bei Leerlauf
  • \n
\n\n

3. Die Bibliothek ratelimit – minimalistischer Ansatz

\n\n

ratelimit ist die einfachste Bibliothek und implementiert ein gleitendes Fenster mit festen Intervallen. Geeignet für einfache Szenarien, in denen keine hohe Genauigkeit erforderlich ist.

\n\n

Beispiel mit ratelimit

\n
use ratelimit::Ratelimiter;\nuse std::time::Duration;\n\nfn main() {\n    let mut limiter = Ratelimiter::builder(10, Duration::from_secs(1))\n        .                    

Empfehlungen