Implementierung von Fallback mit API Gateway
November 10, 2023
API-Resilienz ist die Fähigkeit einer API, schnell zu scheitern oder sicherzustellen, dass sie nach einem Fehler weiterhin funktioniert, wenn sie mit hohem Datenverkehr, Fehlern oder teilweisen Systemausfällen konfrontiert wird. Dies beinhaltet die Implementierung von häufigen API-Resilienz-Designmustern wie Wiederholungsversuche, Timeouts, Circuit Breaker, Failover und Fallbacks. Ein Fallback mit API Gateway ist ein Plan B für eine API – wenn der primäre API-Dienst ausfällt, kann das API Gateway den Datenverkehr an einen sekundären Dienst weiterleiten oder eine vordefinierte Antwort zurückgeben. In diesem Artikel werden wir die Herausforderungen bei bestehenden Fallback-Techniken und die effiziente Implementierung mithilfe des APISIX API Gateways untersuchen.
Implementierung von Fallbacks mit APISIX
Um einen Fallback-Mechanismus mit APISIX zu implementieren, können Sie die integrierte Upstream-Prioritäten-Funktion verwenden oder mit einem response-rewrite-Plugin eine vordefinierte Antwort zurückgeben, wenn ein Dienstaufruf fehlschlägt. Hier ist eine Schritt-für-Schritt-Anleitung, wie Sie beide Fallback-Methoden einrichten können.
Voraussetzung(en)
Diese Anleitung setzt voraus, dass die folgenden Tools lokal installiert sind:
- Bevor Sie beginnen, ist es hilfreich, ein grundlegendes Verständnis von APISIX zu haben. Vertrautheit mit API-Gateways und seinen Schlüsselkonzepten wie Routes, Upstream, Admin API, Plugins und dem HTTP-Protokoll wird ebenfalls von Vorteil sein.
- Docker wird verwendet, um den containerisierten etcd und APISIX zu installieren.
- Installieren Sie cURL, um Anfragen an die Dienste zur Validierung zu senden.
Starten des APISIX Docker-Projekts
Dieses Projekt nutzt die vordefinierte Docker Compose-Konfigurationsdatei, um APISIX, etcd, Prometheus und andere Dienste mit einem einzigen Befehl einzurichten, bereitzustellen und auszuführen. Klonen Sie zunächst das apisix-docker-Repo auf GitHub, öffnen Sie es in Ihrem bevorzugten Editor, navigieren Sie zum Ordner example
und starten Sie das Projekt, indem Sie einfach den Befehl docker compose up
in einem Terminal aus dem Projektstammverzeichnis ausführen.
Wenn Sie das Projekt starten, lädt Docker alle benötigten Images herunter. Es führt auch zwei Beispiel-Backend-Dienste web1
und web2
aus. Die vollständige Liste der Dienste finden Sie in der docker-compose.yaml-Datei.
Fallback mit aktivierten APISIX Upstream-Prioritäten
Sie können jeden Upstream-Knoten mit einer bestimmten Prioritätsstufe einrichten. Wenn der Knotenendpunkt mit der höheren Priorität ausfällt, kann das API-Gateway den Datenverkehr an einen sekundären Knoten mit einer niedrigeren Priorität weiterleiten. Die Standardpriorität für alle Knoten ist 0, Knoten mit negativer Priorität können als Backup konfiguriert werden.
Erstellen Sie eine Route zu den beiden Diensten und konfigurieren Sie das Prioritätsattribut für jeden Upstream-Dienstknoten:
curl "http://127.0.0.1:9180/apisix/admin/routes" -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" -X PUT -d '
{
"id":"backend-service-route",
"methods":[
"GET"
],
"uri":"/get",
"upstream":{
"nodes":[
{
"host":"web1",
"port":80,
"weight":1,
"priority":0
},
{
"host":"web2",
"port":80,
"weight":1,
"priority":-1
}
]
}
}'
methods
: Dies gibt die HTTP-Methode an, die diese Route abgleichen soll. In diesem Fall ist sie so eingestellt, dass sieGET
-Anfragen abgleicht.uri
: Dies ist der Pfad, den die Route abgleichen soll. JedeGET
-Anfrage an/get
wird also von dieser Route verarbeitet.nodes
: Dies ist ein Array von Backend-Servern. Jedes Objekt im Array repräsentiert einen Server mit seinemhost
,port
undweight
. Dasweight
wird für das Load Balancing verwendet; in diesem Fall haben beide Server ein Gewicht von1
, was normalerweise bedeutet, dass sie den Datenverkehr gleichmäßig teilen.priority
: Dies ist eine zusätzliche Konfiguration für die beiden Knoten (web1
,web2
). Das Feldpriority
wird verwendet, um die Reihenfolge zu bestimmen, in der Knoten ausgewählt werden. Ein Knoten mit einer niedrigeren Priorität (eine höhere negative Zahl) wird nur verwendet, wenn alle Knoten mit höherer Priorität (niedrigere negative Zahlen oder positive Zahlen) nicht verfügbar sind.
Überprüfen Sie, ob Sie nur eine Antwort vom web1
-Dienst erhalten, wenn Sie eine Anfrage an die Route senden:
curl "http://127.0.0.1:9080/get"
Sie sollten eine Antwort ähnlich der folgenden sehen:
hello web1
Dies bedeutet, dass web1
zuerst ausgeführt wurde, da es funktioniert. Stoppen Sie nun den web1
-Dienstcontainer, um zu überprüfen, ob APISIX auf den web2
-Dienst zurückfällt.
docker container stop example-web1-1
Wenn Sie jetzt erneut eine Anfrage an die Route senden, erhalten Sie eine Antwort vom angegebenen Fallback-Dienst.
curl "http://127.0.0.1:9080/get"
hello web2
Standardmäßig dauert es 60 Sekunden, während die Anfrage zuerst an Dienst eins geht und auf Dienst zwei zurückfällt, wenn dieser nicht verfügbar ist. Sie können diese Zeit auch ändern, indem Sie das timeout
-Attribut des Upstream-Objekts festlegen. Eine weitere Fallback-Strategie könnte während Releases sein. Wenn eine neue Version der API fehlerhaft ist, können Sie den Datenverkehr auf die alte Version umleiten, die sich im Standby befindet, indem Sie die Traffic Split-Funktion von APISIX verwenden. Fallback auf die vorherige Version, wenn die neue Version Probleme hat. Diese Fallback-Methode funktioniert auch gut mit Upstream-Health-Checks.
Fallback mit dem APISIX Response Rewrite Plugin
Das APISIX response-rewrite-Plugin ermöglicht es Ihnen, den Antwortstatuscode, den Body und die Header zu ändern, bevor sie an den Client zurückgegeben werden. Dies kann besonders nützlich sein, um einen Fallback-Mechanismus zu implementieren, indem eine Standardantwort bereitgestellt wird, wenn der Upstream-Dienst ausfällt.
Wenn Sie den ersten Ansatz befolgt haben, starten Sie den web1
-Dienstcontainer in Docker neu:
docker container start example-web1-1
Um das response-rewrite-Plugin für einen Fallback zu verwenden, müssen Sie es in einer Route konfigurieren. Hier ist ein Beispiel, wie Sie das Plugin mit einem curl
-Befehl aktivieren können:
curl "http://127.0.0.1:9180/apisix/admin/routes" -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" -X PUT -d '
{
"id":"backend-service-route",
"methods":[
"GET"
],
"uri":"/get",
"plugins":{
"response-rewrite":{
"status_code":200,
"body":"{\"message\":\"This is a fallback response when the service is unavailable\"}",
"vars":[
[
"status",
"==",
503
]
]
}
},
"upstream":{
"nodes":{
"web1:80":1
}
}
}'
Im obigen Beispiel haben wir einen einzelnen Backend-Dienst (web1:80
) definiert, an den der Datenverkehr weitergeleitet werden soll, wenn diese Route abgeglichen wird. Wenn der Upstream-Dienst (web1:80
) mit einem 503 Service Unavailable
-Status antwortet, wird das response-rewrite
-Plugin die Antwort so ändern, dass sie einen 200 OK
-Status mit einem benutzerdefinierten JSON-Body hat. Dies erstellt effektiv eine Fallback-Antwort, wenn der Upstream-Dienst nicht verfügbar ist.
"vars": [["status", "==", 503]]
: Diese Bedingung weist das Plugin an, die Umschreibung nur anzuwenden, wenn der ursprüngliche Statuscode der Antwort503 Service Unavailable
ist.
Wenn Sie jetzt eine Anfrage an die Route senden, sollten Sie eine modifizierte Antwort erhalten:
curl "http://127.0.0.1:9080/get"
{"message":"This is a fallback response when the service is unavailable"}
Herausforderungen bei der Implementierung eines Fallback-Mechanismus
Fallbacks sind eine kritische Komponente eines resilienten Systemdesigns. Sie können jedoch mehr Probleme verursachen, wenn sie falsch implementiert werden. Bei der Diskussion von Fallback-Strategien können die Herausforderungen in Einzelmaschinenumgebungen und verteilten Systemen unterschiedlich sein. Lassen Sie uns diese überprüfen, um sie anhand von Beispielen zu verstehen und zu lernen, wie man sie mit APISIX vermeiden kann.
Schwierigkeiten beim Testen der Fallback-Logik
Es ist schwierig, Anwendungsfehlerbedingungen wie einen Datenbankausfall in einer Einzelmaschinenumgebung genau zu simulieren. Das Testen von Fallback-Strategien in verteilten Systemen wird noch komplexer, da mehrere Maschinen und Dienste beteiligt sind, was es schwierig macht, alle möglichen Fehlermodi zu replizieren. Beispielsweise hat eine API auf einem lokalen Server einen Fallback auf eine zwischengespeicherte Antwort, wenn die Datenbank nicht erreichbar ist. Das Testen dieses Szenarios erfordert die Simulation eines Datenbankausfalls, der möglicherweise nicht Teil des regulären Testens ist, was zu ungetestetem Fallback-Code unter tatsächlicher Produktionslast führt.
APISIX kann so konfiguriert werden, dass es den Datenverkehr zur Simulation verschiedener Szenarien, einschließlich Fallback-Bedingungen, weiterleitet. Dies ermöglicht realistischeres Testen der Fallback-Logik unter kontrollierten Bedingungen und stellt sicher, dass die Fallback-Dienste den Produktionsdatenverkehr bewältigen können.
Fallbacks selbst können scheitern
Wenn eine Fallback-Lösung nicht so resilient ist wie erwartet, könnte sie unter der erhöhten Last, die auftritt, wenn sie in Aktion tritt, scheitern und einen kaskadierenden Ausfall verursachen. Außerdem kann ein Fallback auf einen weniger effizienten Dienst die Antwortzeiten und die Last erhöhen, was möglicherweise zu einer systemweiten Verlangsamung oder einem Ausfall führt. Beispielsweise könnte eine API einen Fallback haben, um Protokolle in ein lokales Dateisystem zu schreiben, wenn ein Remote-Protokollierungsdienst nicht verfügbar ist. Dies könnte zu einer langsameren Leistung aufgrund synchroner Datei-I/O-Operationen führen.
Mit APISIX können Sie den Datenverkehr priorisieren, um sicherzustellen, dass kritische Anfragen zuerst verarbeitet werden. Dies kann verhindern, dass ein Fallback-Dienst überlastet wird und die Leistung des Systems verschlechtert.
Fallbacks haben betriebliche Risiken
Die Implementierung eines Fallbacks könnte neue Ausfallpunkte einführen, wie z. B. eine sekundäre Datenbank, die nicht mit der primären synchronisiert wird, was zu Dateninkonsistenzen führen kann.
Die Beobachtbarkeitsfunktionen von APISIX, wie Protokollierung, Metriken und Tracing, können die Gesundheit und Leistung sowohl der primären als auch der Fallback-Dienste überwachen. Diese Echtzeitüberwachung kann helfen, Risiken im Zusammenhang mit Fallback-Strategien zu identifizieren und zu mindern.
Fallbacks haben latente und verstärkte Fehler
Fallback-Codepfade können inaktive Fehler enthalten, die nur unter bestimmten Fehlerbedingungen auftreten, die möglicherweise nicht oft vorkommen und schwer vorherzusagen sind, und die möglicherweise monate- oder jahrelang unentdeckt bleiben. Beispielsweise könnte ein Fallback-Mechanismus in einer API, der bei einem Ausfall des Identitätsdienstes auf eine andere Authentifizierungsmethode umschaltet, einen Fehler enthalten, der nur auftritt, wenn der Fallback ausgelöst wird, was ein seltenes Ereignis sein könnte.
APISIX unterstützt kontinuierliches A/B-Testing und Canary Releases, was es Teams ermöglicht, Fallback-Pfade in der Produktion mit einem kleinen Prozentsatz des Datenverkehrs zu testen. Diese kontinuierliche Exposition kann helfen, latente Fehler aufzudecken, bevor sie kritisch werden.
Fallbacks werden selten genutzt
Fallback-Mechanismen werden selten genutzt, daher können sie, wenn sie ausgelöst werden, möglicherweise nicht wie erwartet funktionieren, da sie nicht regelmäßig getestet und aktualisiert werden. Beispielsweise könnte eine API, die geografische Daten bereitstellt, einen Fallback auf einen statischen Datensatz haben, wenn die dynamische Datenquelle nicht verfügbar ist. Wenn dieser Fallback selten genutzt wird, könnte er veraltete Informationen liefern, wenn er aktiviert wird, da er nicht regelmäßig aktualisiert oder getestet wird.
Andererseits ermöglicht APISIX die Konfiguration von dynamischem Routing und kann verwendet werden, um regelmäßig einen Teil des Datenverkehrs an die Fallback-Dienste weiterzuleiten. Dies stellt sicher, dass die Fallback-Pfade regelmäßig genutzt werden und einsatzbereit bleiben.
Fazit
Fallbacks sind ein Sicherheitsnetz für den Fall, dass mit APIs etwas schiefgeht. Durch die Verwendung der Upstream-Konfiguration oder des response-rewrite-Plugins von APISIX können Entwickler durchdachte, benutzerfreundliche Antworten bereitstellen, die das System funktionsfähig halten und das Vertrauen der Benutzer bewahren. Der Schlüssel liegt darin, potenzielle Ausfallpunkte vorherzusehen und Fallbacks zu entwerfen, die unter den gegebenen Umständen die bestmögliche Erfahrung bieten.