Rate Limiting in Node.js: Vollständiger Leitfaden zum Schutz von APIs und Lastmanagement

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 Node.js: Schutz von APIs vor Überlastung und Angreifern

\n\n

Rate Limiting (Anfragegeschwindigkeitsbegrenzung) ist ein kritisch wichtiger Mechanismus für jede Webanwendung in Node.js. Er ermöglicht es, die Anzahl der Anfragen zu kontrollieren, die ein Client innerhalb eines bestimmten Zeitraums an den Server senden kann. Ohne Rate Limiting ist Ihre API anfällig für DDoS-Angriffe, zufällige Überlastungen und übermäßigen Ressourcenverbrauch.

\n\n

Warum ist Rate Limiting notwendig?

\n
    \n
  • Schutz vor Brute-Force: Verhindert mehrfache Anmeldeversuche.
  • \n
  • DDoS-Prävention: Begrenzt die Auswirkungen von Denial-of-Service-Angriffen.
  • \n
  • Faire Ressourcenverteilung: Garantiert gleichen Zugang für alle Benutzer.
  • \n
  • Kosteneinsparung: Reduziert die Last auf Servern und Datenbanken.
  • \n
  • SLA-Einhaltung: Erfüllung von Service-Level-Agreements.
  • \n
\n\n

Wichtige Rate-Limiting-Algorithmen

\n

Es gibt mehrere Ansätze zur Implementierung der Geschwindigkeitsbegrenzung. Betrachten wir die gängigsten:

\n\n

1. Sliding Window (Gleitendes Fenster)

\n

Der häufigste Algorithmus. Anfragen werden in Zeitfenstern gruppiert (z. B. 1 Minute). Überschreitet die Anzahl der Anfragen das Limit, werden weitere Anfragen bis zum Beginn eines neuen Fensters abgelehnt.

\n\n

2. Token Bucket (Token-Eimer)

\n

Ein virtueller "Eimer" enthält Token. Jede Anfrage verbraucht einen Token. Token werden mit einer festen Rate aufgefüllt. Ist der Eimer leer, wird die Anfrage abgelehnt.

\n\n

3. Leaky Bucket (Undichter Eimer)

\n

Anfragen gelangen in eine Warteschlange und werden mit konstanter Geschwindigkeit verarbeitet. Wenn die Warteschlange überläuft, werden Anfragen verworfen.

\n\n

Bibliotheken für Rate Limiting in Node.js

\n\n

1. express-rate-limit

\n

Die beliebteste Bibliothek für Express.js. Einfach zu verwenden und anpassbar.

\n\n
const rateLimit = require('express-rate-limit');\n\n// Middleware zur Anfragebegrenzung erstellen\nconst limiter = rateLimit({\n  windowMs: 15 * 60 * 1000, // 15 Minuten\n  max: 100, // maximal 100 Anfragen pro Fenster\n  message: 'Zu viele Anfragen, bitte später versuchen.',\n  standardHeaders: true, // Gibt RateLimit-*-Header zurück\n  legacyHeaders: false, // Deaktiviert X-RateLimit-*-Header\n});\n\n// Auf alle Routen anwenden\napp.use(limiter);\n\n// Oder nur auf eine bestimmte Route\napp.use('/api/login', limiter);\n
\n\n

2. bottleneck

\n

Eine universelle Bibliothek, die mit beliebigen asynchronen Operationen arbeitet. Unterstützt die Algorithmen Token Bucket und Leaky Bucket.

\n\n
const Bottleneck = require('bottleneck');\n\n// Limiter erstellen: 5 Anfragen pro Sekunde\nconst limiter = new Bottleneck({\n  minTime: 200, // 200 ms zwischen Anfragen\n  maxConcurrent: 5, // maximal 5 gleichzeitige Anfragen\n  reservoir: 100, // anfängliche Token-Anzahl\n  reservoirRefreshAmount: 100,\n  reservoirRefreshInterval: 60 * 1000, // Auffüllung einmal pro Minute\n});\n\n// Funktion in Limiter einschließen\nasync function fetchData(url) {\n  const response = await fetch(url);\n  return response.json();\n}\n\nconst limitedFetch = limiter.wrap(fetchData);\n\n// Verwendung\nconst data = await limitedFetch('https://api.example.com/data');\n
\n\n

3. rate-limiter-flexible

\n

Eine flexible Bibliothek mit Unterstützung für Redis, MongoDB, Memcached und andere Speicher. Ideal für verteilte Systeme.

\n\n
const { RateLimiterRedis } = require('rate-limiter-flexible');\nconst Redis = require('ioredis');\n\nconst redisClient = new Redis();\n\nconst rateLimiter = new RateLimiterRedis({\n  storeClient: redisClient,\n  keyPrefix: 'middleware',\n  points: 10, // 10 Anfragen\n  duration: 1, // pro 1 Sekunde\n});\n\napp.use(async (req, res, next) => {\n  try {\n    await rateLimiter.consume(req.ip);\n    next();\n  } catch (rejRes) {\n    res.status(429).send('Zu viele Anfragen');\n  }\n});\n

Empfehlungen