Skip to content
IRC-Coding IRC-Coding
Rate Limiting Redis Implementierung Distributed Systems API Gateway Token Bucket

API Rate Limiting Implementierung: Praktische Umsetzung für verteilte Systeme

Lerne API Rate Limiting Implementierung: Algorithmen, Redis, Header, Code-Beispiele, Fehlerbehandlung und Best Practices für verteilte APIs.

S

schutzgeist

2 min read
API Rate Limiting Implementierung: Praktische Umsetzung für verteilte Systeme

API Rate Limiting Implementierung

API Rate Limiting in verteilten Systemen erfordert konsistente Zustandsverwaltung, die richtige Algorithmuswahl und eine klare Kommunikation mit Clients.

Kompakte Beschreibung

API Rate Limiting Implementierung beschreibt die technische Umsetzung von Begrenzungen für Anfragen an eine API. In verteilten Systemen muss das Limit über alle Instanzen hinweg konsistent gelten, was einen zentralen Speicher wie Redis oder eine Datenbank erfordert. Die wichtigsten Algorithmen sind Fixed Window, Sliding Window, Token Bucket und Leaky Bucket. Jeder Algorithmus hat unterschiedliche Eigenschaften bezüglich Fairness, Burst-Verhalten und Implementierungsaufwand. Bei der Implementierung müssen entscheidende Details wie die Identifikation des Clients, atomare Operationen, Header für die Statusanzeige, Fehlerbehandlung mit 429 und Retry-After, sowie die Wahl der richtigen Limits berücksichtigt werden. Rate Limiting sollte nicht nur im Anwendungscode, sondern auch im API Gateway oder Load Balancer konfiguriert werden können, um Schutz auf mehreren Ebenen zu bieten.

Wichtige Komponenten

Client-Identifikation

Rate Limiting benötigt eine eindeutige Identifikation des Clients. Dazu können API Keys, Nutzer-IDs, IP-Adressen oder Kombinationen aus mehreren Faktoren verwendet werden. Für authentifizierte Clients ist die Nutzer-ID meist die beste Wahl, da IP-Adressen sich ändern und mehrere Clients hinter einer IP teilen können.

Fixed Window Implementierung

Fixed Window zählt Anfragen in festen Zeitfenstern. In Redis kann ein Zähler pro Fenster und Client gespeichert werden. Der Zähler wird bei der ersten Anfrage im Fenster erstellt und läuft nach Ablauf der Zeit ab. Überschreitet der Zähler das Limit, wird die Anfrage abgelehnt.

Sliding Window Implementierung

Sliding Window ist fairer als Fixed Window, aber komplexer. Eine Variante ist Sliding Window Log, bei dem für jeden Client eine Liste von Zeitstempeln der letzten Anfragen gespeichert wird. Anfragen, die außerhalb des Fensters liegen, werden entfernt. Ist die Anzahl der verbleibenden Anfragen höher als das Limit, wird die Anfrage abgelehnt.

Token Bucket Implementierung

Token Bucket ist ein häufig verwendeter Algorithmus. Ein Bucket hat eine maximale Kapazität und wird mit Token mit konstanter Rate aufgefüllt. Jede Anfrage verbraucht ein Token. Ist der Bucket leer, wird die Anfrage abgelehnt oder verzögert. Redis eignet sich gut für Token Bucket mit Lua-Skripten für atomare Operationen.

Leaky Bucket Implementierung

Leaky Bucket verarbeitet Anfragen mit konstanter Rate. Anfragen werden in einer Warteschlange zwischengespeichert und gleichmäßig abgearbeitet. er Algorithmus ist gut für gleichmäßige Verarbeitung, kann aber zu Wartezeiten und Auswurf bei voller Queue führen.

Redis für verteiltes Rate Limiting

Redis bietet schnelle atomare Operationen und TTL, was es ideal für Rate Limiting macht. Lua-Skripte ermöglichen es, mehrere Befehle atomar auszuführen. Redis Cluster oder Redis Sentinel sorgen für Hochverfügbarkeit. Bei sehr hohen Anforderungen kann Redis als zentraler Bottleneck auftreten, weshalb Caching oder lokale Proxy-Caches ergänzt werden können.

Atomare Operationen

Rate Limiting muss atomar sein, um Race Conditions zu vermeiden. Wenn mehrere Anfragen gleichzeitig prüfen, ob noch Limit verfügbar ist, darf das Limit nicht überschritten werden. Lua-Skripte in Redis oder Transaktionen in Datenbanken helfen, Atomarität zu gewährleisten.

Header für Statusanzeige

Clients sollten über ihren aktuellen Status informiert werden. Header wie X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset sind weit verbreitet. Alternativ kann das RFC-RateLimit-Schema verwendet werden. Diese Header ermöglichen es Clients, ihre Anfragerate anzupassen.

Fehlerbehandlung mit 429

Wenn das Limit überschritten ist, antwortet die API mit 429 Too Many Requests. Der Retry-After Header sollte angeben, wann der Client es erneut versuchen darf. Die Fehlerantwort sollte nach RFC 7807 Problem Details formatiert sein und keine Interna enthalten.

Per-Endpoint und Per-User Limits

Unterschiedliche Endpunkte haben unterschiedliche Kosten. Schreiboperationen und teure Abfragen sollten strengere Limits haben als einfache Leseoperationen. Ebenso können unterschiedliche Nutzergruppen unterschiedliche Limits erhalten, beispielsweise kostenlose und zahlende Kunden.

Rate Limiting im API Gateway

API Gateways wie Kong, Nginx oder AWS API Gateway bieten eingebautes Rate Limiting. Sie schützen die API, bevor Anfragen das Backend erreichen. Gateways sind besonders effektiv für globale Limits und einfache Regeln, während Anwendungscode komplexere, nutzerspezifische Regeln umsetzen kann.

Praxisbeispiel

Ein Node.js Service implementiert Token Bucket Rate Limiting mit Redis.

const redis = require('redis');
const client = redis.createClient();

const LIMIT = 100;
const WINDOW_SECONDS = 60;

async function isAllowed(clientId) {
  const key = `rate_limit:${clientId}`;
  const lua = `
    local key = KEYS[1]
    local limit = tonumber(ARGV[1])
    local window = tonumber(ARGV[2])
    local current = redis.call('GET', key)
    if current == false then
      current = 0
    end
    current = tonumber(current)
    if current >= limit then
      return 0
    end
    redis.call('INCR', key)
    if current == 0 then
      redis.call('EXPIRE', key, window)
    end
    return 1
  `;

  const result = await client.eval(lua, { keys: [key], arguments: [String(LIMIT), String(WINDOW_SECONDS)] });
  return result === 1;
}

Middleware im Express:

async function rateLimit(req, res, next) {
  const clientId = req.user?.id || req.ip;
  const allowed = await isAllowed(clientId);
  if (!allowed) {
    res.set('Retry-After', String(WINDOW_SECONDS));
    return res.status(429).json({
      type: 'https://api.example.com/problems/rate-limit-exceeded',
      title: 'Rate Limit überschritten',
      status: 429,
      detail: `Du hast das Limit von ${LIMIT} Anfragen pro ${WINDOW_SECONDS} Sekunden überschritten.`
    });
  }
  next();
}

Dieser Ansatz ist atomar, funktioniert über mehrere Server-Instanzen hinweg und kommuniziert Limits klar an den Client.

FAQ: API Rate Limiting Implementierung

1. Wie identifiziert man einen Client für Rate Limiting?

Clients werden meist durch API Keys, Nutzer-IDs oder IP-Adressen identifiziert. Für authentifizierte APIs ist die Nutzer-ID meist die zuverlässigste Wahl.

2. Warum ist Redis für Rate Limiting geeignet?

Redis ist schnell, bietet atomare Operationen und TTL, und ist in verteilten Systemen zentral erreichbar. Lua-Skripte ermöglichen komplexe atomare Zähloperationen.

3. Was ist ein Token Bucket in der Implementierung?

Ein Token Bucket wird mit Token mit konstanter Rate aufgefüllt. Jede Anfrage verbraucht ein Token. Ist der Bucket leer, wird die Anfrage abgelehnt. Redis und Lua-Skripte ermöglichen eine atomare Implementierung.

4. Was ist atomares Rate Limiting?

Atomares Rate Limiting stellt sicher, dass die Prüfung und Aktualisierung des Limits als eine unteilbare Operation erfolgen. Das verhindert Race Conditions und Limitüberschreitungen bei parallelen Anfragen.

5. Was ist ein Sliding Window Log?

Sliding Window Log speichert Zeitstempel jeder Anfrage für einen Client. Anfragen außerhalb des Fensters werden entfernt. Ist die Anzahl der verbleibenden Anfragen höher als das Limit, wird die Anfrage abgelehnt.

6. Was ist Fixed Window?

Fixed Window zählt Anfragen in festen Zeitfenstern. Es ist einfach zu implementieren, kann aber zu Bursts am Ende und Beginn eines Fensters führen.

7. Was ist Leaky Bucket?

Leaky Bucket stellt Anfragen in einer Warteschlange und verarbeitet sie mit konstanter Rate. Es glättet Traffic sehr stark, kann aber zu Wartezeiten führen.

8. Was ist Race Condition beim Rate Limiting?

Eine Race Condition entsteht, wenn mehrere parallele Anfragen gleichzeitig prüfen und aktualisieren. Ohne atomare Operationen kann das Limit überschritten werden.

9. Welche Header sollten bei Rate Limiting gesetzt werden?

Header wie X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset und Retry-After informieren Clients über ihr Limit und den nächsten erlaubten Zeitpunkt.

10. Was ist 429 Too Many Requests?

429 Too Many Requests ist der HTTP-Statuscode, der anzeigt, dass ein Client das Rate Limit überschritten hat. Zusammen mit Retry-After ermöglicht er eine faire Wiederholung.

11. Sollte Rate Limiting im Gateway oder im Code passieren?

Beides ist sinnvoll. Gateways eignen sich für globale und einfache Limits, Anwendungscode für komplexere, nutzer- oder endpunktspezifische Regeln.

12. Was sind Per-Endpoint Limits?

Per-Endpoint Limits gelten für einzelne Endpunkte. Schreiboperationen und teure Abfragen erhalten oft strengere Limits als einfache Leseoperationen.

13. Was ist ein Rate Limiting Bottleneck?

Ein Bottleneck entsteht, wenn der zentrale Speicher für Rate Limiting, wie Redis, überlastet wird. Lösungen sind Caching, lokale Proxy-Caches oder eine optimierte Datenstruktur.

14. Was ist eine gute Rate Limiting Strategie?

Eine gute Strategie kombiniert Client-Identifikation, den richtigen Algorithmus, atomare Operationen, informierende Header, sinnvolle Limits pro Endpunkt und Nutzer, klare Fehlerbehandlung und Monitoring.

15. Was ist der Vorteil von Retry-After?

Retry-After teilt dem Client mit, wann er die Anfrage erneut senden darf. Das reduziert unnötige Anfragen, schont die API und verbessert die Erfolgsrate bei Wiederholungen.

Quellen

  1. https://www.rfc-editor.org/rfc/rfc6585
  2. https://redis.io/docs/manual/programmability/eval-intro/
  3. https://www.konghq.com/kong

Buchempfehlungen zur API-Entwicklung

Wenn Du Dich weiter mit Rate Limiting, verteilten Systemen und API-Architektur beschäftigen möchtest, empfehlen wir Dir die folgenden Bücher:

Keine Bücher für Kategorie "api-development" gefunden.

Zurück zum Blog
Share:

Ähnliche Beiträge