BLOG | NGINX

Batchverarbeitung von API-Anfragen mit NGINX Plus und dem NGINX JavaScript-Modul

NGINX-Teil-von-F5-horiz-schwarz-Typ-RGB
Rick Nelson Miniaturbild
Rick Nelson
Veröffentlicht am 24. Mai 2018

Die mit NGINX Plus R15 veröffentlichte Version des NGINX-JavaScript-Moduls kann jetzt Unteranforderungen ausgeben, was bedeutet, dass Anforderungen im JavaScript-Code initiiert werden können. Dadurch kann ein ganz neuer Satz von Anwendungsfällen adressiert werden.

Einer dieser Anwendungsfälle ist die Stapelverarbeitung von API-Anfragen, sodass eine einzelne API-Anfrage eines Clients in mehrere API-Anfragen an eine Reihe von Backend-Servern umgewandelt und die Antworten zu einer einzigen Antwort an den Client zusammengefasst werden können. In diesem Blog verwenden wir eine E-Commerce-Site als Beispiel – wenn der Kunde Informationen zu einem bestimmten Produkt anfordert, werden Unteranfragen an drei Back-End-Dienste gestellt: Katalog, Lager und Kundenrezensionen.

Dieser Beitrag baut auf dem Subrequest-Beispiel in der NGINX Plus R15 -Ankündigung auf, das zeigt, wie Subrequests verwendet werden, um dieselbe Anfrage an zwei Backend-Server zu senden und nur die erste Antwort an den Client zurückzugeben.

[ Herausgeber – Dieser Beitrag ist einer von mehreren, die Anwendungsfälle für das NGINX-JavaScript-Modul untersuchen. Eine vollständige Liste finden Sie unter Anwendungsfälle für das NGINX-JavaScript-Modul .

Der Beitrag wurde aktualisiert, um die Direktive js_import zu verwenden, die die Direktive js_include in NGINX Plus R23 und höher ersetzt. Weitere Informationen finden Sie in der Referenzdokumentation für das NGINX-JavaScript-Modul – der Abschnitt „Beispielkonfiguration“ zeigt die richtige Syntax für die NGINX-Konfiguration und JavaScript-Dateien. ]

Einführung

Das Ziel dieses Beitrags besteht darin, funktionierende Beispiele für die einfache und unkomplizierte Batchverarbeitung von API-Anforderungen bereitzustellen. Die Beispiele erfüllen alle der folgenden Anforderungen:

  • Für alle Anfragen wird die HTTP- GET -Methode verwendet.
  • Alle Antworten sind im JSON-Format.
  • Es werden zwei Arten von API-Anfragen unterstützt:

    • Das Argument für das API-Programm ist das letzte Element der URI. Wir nennen dies den Anforderungsstil des letzten Elements . In unserem Beispiel erzeugt eine Clientanforderung für /batch-api/product/14286 Anforderungen an /myapi/catalog/14286 , /myapi/inventory/14286 und /myapi/review/14286 .
    • Das Argument wird in der Abfragezeichenfolge der URI identifiziert. Wir nennen dies den Abfragezeichenfolgen-Anforderungsstil . Im Beispiel erzeugt eine Anfrage für /batch-api2/product?item=14286 Anfragen an /myapi/catalog.php?item=14286 , /myapi/inventory.php?item=14286 und /myapi/review.php?item=14286 .

    Beachten Sie, dass bei beiden Stilen zusätzliche Argumente in der Abfragezeichenfolge enthalten sein können.

  • Der Satz von Unteranfragen, der durch eine Clientanfrage ausgelöst wird, ist dynamisch konfigurierbar, d. h. wir können ihn ändern, ohne die NGINX Plus-Konfiguration manuell zu bearbeiten und neu zu laden.
  • Die API-Anfragen an die Backend-Server sind voneinander unabhängig.

Lösungsübersicht

Zusätzlich zur Verwendung der neuen Subrequest-Funktion von NGINX JavaScript nutzt diese Lösung die Schlüssel-Wert-Speicherfunktion von NGINX Plus, wodurch Konfigurationsänderungen dynamisch mit der NGINX Plus-API vorgenommen werden können.

Die folgenden Grafiken veranschaulichen die beiden unterstützten Anforderungsstile.

Anforderungsstil für letztes Element:

Der Client stellt Anfragen im Final-Element-Stil an eine API

Abfragezeichenfolgen-Anforderungsstil:

Der Client stellt Anfragen im Abfragezeichenfolgenstil an eine API

In beiden Beispielen muss der Kunde Informationen zu einem Produkt aus dem Katalog, dem Lagerbestand und den Bewertungsdiensten abrufen. Es sendet eine Anfrage an NGINX Plus und übergibt die Artikelnummer entweder als Teil der URI oder in der Abfragezeichenfolge. Anschließend werden Anfragen an die drei Dienste gesendet und die Antworten zu einer einzigen Antwort an den Client zusammengefasst.

Damit dies mit NGINX Plus funktioniert, sind zwei Komponenten erforderlich: ein JavaScript-Programm und die NGINX Plus-Konfiguration .

Das JavaScript-Programm

Für jede Client-Anfrage wird die JavaScript-Funktion batchAPI() aufgerufen. Es ruft die durch Kommas getrennte Liste der API-URIs aus dem Schlüssel-Wert-Speicher ab, durchläuft sie und stellt für jede eine Unteranforderung, wobei die Rückruffunktion done() angegeben wird, um jede Antwort zu verarbeiten. Bei Anfragen im Stil des letzten Elements wird das letzte Element der URI, das in der NGINX-Variable $uri_suffix gespeichert ist, als Abfragezeichenfolge jeder Unteranfrage zusammen mit allen anderen Abfragezeichenfolgenargumenten in der ursprünglichen Client-URI übergeben. Bei Anfragen im Stil der Abfragezeichenfolge wird die Abfragezeichenfolge aus den Clientanfragen als Abfragezeichenfolge jeder Unteranfrage übergeben.

Die Aufrufe erfolgen in der Reihenfolge, in der sie im Schlüssel-Wert-Speicher aufgeführt sind, sind jedoch asynchron, sodass die Antworten in beliebiger Reihenfolge zurückgegeben werden können. Die Antworten werden in der Reihenfolge ihres Eingangs zu einer Antwort an den Client zusammengefasst. Hier ist eine minimale Version des JavaScript-Programms:

Eine Version des JavaScript-Programms mit umfassenderer Fehlerbehandlung, Protokollierung und Kommentaren ist im GitHub Gist-Repository als batch-api.js verfügbar.

Minimale NGINX Plus-Konfiguration

Die folgende NGINX Plus-Konfiguration implementiert die beiden oben besprochenen Anforderungsstile unter Verwendung einer Gruppe von Upstream-Servern. Der Einfachheit halber geht diese Konfiguration davon aus, dass die Upstream-Server einen Aufruf der Form /myapi/ service / item# (Formatvorlage des letzten Elements) in /myapi/service.php/?item=item# ( Formatvorlage der Abfragezeichenfolge) übersetzen können. Dabei handelt es sich um das „native“ URI-Format für PHP, die Sprache für unseren Beispielkatalog sowie für Inventar- und Überprüfungsdienste.

Eine umfangreichere NGINX Plus-Konfiguration, die die Übersetzung selbst durchführt, finden Sie weiter unten unter „Erweitern der NGINX-Konfiguration zum Übersetzen von URIs“ .

Schauen wir uns die Konfigurationsdatei Abschnitt für Abschnitt an und erklären, was jeder Teil macht:

  • Importieren Sie die JavaScript-Datei :

  • Definieren Sie einen Schlüssel-Wert-Speicher zur Speicherung der Liste der API-Anfragen, wobei das letzte Element der URI das Argument für das API-Programm identifiziert. Der Schlüssel verwendet die Variable $uri_prefix, um den Teil der URI vor dem letzten / zu erfassen:

    In NGINX Plus R16 und höher können Sie zwei zusätzliche Schlüssel-Wert-Funktionen nutzen:

    • Legen Sie eine Ablaufzeit für die Einträge in einem Schlüssel-Wert-Speicher fest, indem Sie der Direktive keyval_zone den Parameter timeout hinzufügen. Um beispielsweise jeden Batch-URI täglich ablaufen zu lassen, fügen Sie timeout=1d hinzu.
    • Synchronisieren Sie den Schlüssel-Wert-Speicher über einen Cluster von NGINX Plus-Instanzen hinweg, indem Sie der Direktive „ keyval_zone“ den Synchronisierungsparameter hinzufügen. In diesem Fall müssen Sie auch den Timeout- Parameter mit einbeziehen.

    Anweisungen zum Einrichten der Synchronisierung für Schlüssel-Wert-Speicher finden Sie im NGINX Plus-Administratorhandbuch .

  • Definieren Sie einen anderen Schlüssel-Wert-Speicher für APIs, in denen das Argument in der Abfragezeichenfolge identifiziert wird. Hier erfasst der Schlüssel ( $uri ) die gesamte URI, ohne die Abfragezeichenfolge:

  • Definieren Sie zwei Maps, um die URI in zwei Teile aufzuteilen für APIs, die Anfragen akzeptieren, bei denen das Argument das letzte Element der URI ist. Die Variable $uri_prefix erfasst die URI-Elemente vor dem letzten / und $uri_suffix erfasst das letzte Element:

  • Definieren Sie die Upstream-Gruppe der API-Server (hier werden sie zusammen mit NGINX Plus auf localhost ausgeführt):

  • Definieren Sie den virtuellen Server , der Clientanforderungen und Unteranforderungen verarbeitet:

  • Definieren Sie einen Speicherort für die Verarbeitung von Clientanforderungen, die den Final‑Element‑Stil verwenden. Dies wird der batchAPI‑ Funktion angezeigt, indem die Variable $batch_api_arg_in_uri auf on gesetzt wird:

  • Definieren Sie einen Speicherort für die Verarbeitung von Clientanforderungen, die den Abfragezeichenfolgenstil verwenden. Dies wird der batchAPI -Funktion angezeigt, indem die Variable $batch_api_arg_in_uri auf off gesetzt wird:

  • Definieren Sie den Speicherort, der die Unteranforderungen verarbeitet:

  • Aktivieren Sie die NGINX Plus-API , damit Daten im Schlüssel-Wert-Speicher verwaltet werden können:

Hier ist die vollständige Konfiguration:

Konfigurieren der Batch-API-Anfragen

Wir verwenden die Schlüssel-Wert-Speicherfunktion von NGINX Plus, um eingehende Clientanforderungen einer Reihe von auszuführenden API-Anforderungen zuzuordnen. Die Konfiguration im vorherigen Abschnitt definiert separate Schlüssel‑Wert‑Speicher für die beiden Anforderungsstile:

  • Der Schlüssel-Wert-Speicher für den Final-Element-Stil heißt batch_api und der Schlüssel ist die Variable $uri_prefix , die die Elemente vor dem letzten / der Anforderungs-URI erfasst.
  • Der Schlüssel-Wert-Speicher für den Abfragezeichenfolgenstil heißt batch_api2 und der Schlüssel ist die Variable $uri , die die vollständige Anforderungs-URI ohne die Abfragezeichenfolge erfasst.

In beiden Schlüssel-Wert-Speichern ist der jedem Schlüssel zugeordnete Wert eine durch Kommas getrennte Liste von URIs, die zur Laufzeit in den Variablen „$batch_api“ oder „$batch_api2“ verfügbar gemacht werden.

Für Anfragen im Final‑Element‑Stil möchten wir eine Client‑Anfrage für /batch-api/product Anfragen an die drei Dienste /myapi/catalog , /myapi/inventory und /myapi/review zuordnen, sodass eine Anfrage für /batch-api/product/14286 Anfragen an /myapi/catalog/14286 , /myapi/product/14286 und /myapi/review/14286 ergibt.

Um diese Zuordnungen zum Schlüssel-Wert-Speicher der batch_api hinzuzufügen, senden wir die folgende Anfrage an die auf dem lokalen Computer ausgeführte NGINX Plus-Instanz:

$ curl -iX POST -d '{"/batch-api/product":"/myapi/catalog,/myapi/inventory,/myapi/review"}' http://localhost/api/3/http/keyvals/batch_api

Für die Anfragen im Abfragezeichenfolgenstil möchten wir eine Clientanfrage für /batch-api2/product Anfragen an die drei Dienste /myapi/catalog.php , /myapi/inventory.php und /myapi/review.php zuordnen, sodass eine Anfrage für /batch-api2/product?item=14286 Anfragen an /myapi/catalog?item=14286 , /myapi/product?item=14286 und /myapi/review?item=14286 ergibt.

Um diese Zuordnungen zum Schlüssel-Wert-Speicher batch_api2 hinzuzufügen, senden wir diese Anfrage:

$ curl -iX POST -d '{"/batch-api2/product":"/myapi/catalog.php,/myapi/inventory.php,/myapi/review.php"}' http://localhost/api/3/http/keyvals/batch_api2

Ausführen der Beispiele

Dieselben PHP-Seiten verarbeiten Anfragen, die in beiden Anfragestilen gestellt werden. Der Einfachheit halber gehen wir davon aus, dass die Backend-Server in der Lage sind, URIs im Stil des letzten Elements ( /myapi/ service / item# ) in URIs im Stil der Abfragezeichenfolge ( /myapi/ service .php?item= item# ) zu übersetzen. Es ist nicht erforderlich, URIs im Abfragezeichenfolgenstil zu übersetzen, da dies das „native“ URI-Format für PHP-Programme ist.

Alle Dienste geben eine Antwort im JSON-Format zurück, die den Dienstnamen und das Elementarargument enthält. Beispielsweise führt eine Anfrage nach /myapi/catalog.php?item=14286 zu der folgenden Antwort von catalog.php :

{"service":"Katalog","item":"14286"}

Obwohl die in diesen Beispielen verwendeten PHP-Programme den Dienstnamen in der Antwort enthalten, ist dies möglicherweise nicht bei allen Diensten der Fall. Um die Antworten den Diensten zuzuordnen, die sie generiert haben, schließt das JavaScript-Programm die URI in die aggregierte Antwort ein.

Beispielsweise lautet die aggregierte Antwort auf eine Anforderung für /batch-api/product/14286 wie folgt (die Reihenfolge der drei Komponentenantworten kann jedoch variieren):

[["/myapi/review/14286",{"service":"Rezension","item":"14286"}],["/myapi/inventory/14286",{"service":"Inventar","item":"14286"}],["/myapi/catalog/14286",{"service":"Katalog","item":"14286"}]]

Erweitern der NGINX Plus-Konfiguration zum Übersetzen von URIs

Wie erwähnt, geht die oben besprochene minimale NGINX Plus-Konfiguration davon aus, dass die API-Server in der Lage sind, URIs im Format /myapi/ service / item# in /myapi/ service .php/?item= item# zu übersetzen. Wir können die Übersetzung auch in der NGINX Plus-Konfiguration implementieren, indem wir die folgenden Änderungen vornehmen.

  • Fügen Sie eine neue Upstream-Gruppe hinzu, um die Unteranforderungen zu empfangen:

  • Fügen Sie einen neuen virtuellen Server hinzu, um auf Anfragen zu warten, die von der Upstream-Gruppe der Dienste empfangen werden. Wenn Anfragen im Abfragezeichenfolgenstil empfangen werden, werden sie einfach an die Upstream-Gruppe „API_Servers“ weitergeleitet, da die URI bereits die Erweiterung .php hat. Wenn Anfragen im Final‑Element‑Stil empfangen werden, wird die URI so umgeschrieben, dass das letzte Element in der URI entfernt und in ein Abfragezeichenfolgenargument konvertiert wird:

  • Ändern Sie den Speicherort /myapi, um einen Proxy für die neue Upstream-Gruppe bereitzustellen:

Hier ist die vollständige Konfiguration:

Zusätzliche Komponenten

Die Beispielprogramme in JavaScript und die Konfigurationen von NGINX Plus können an andere API-Stile angepasst werden. Wenn Sie jedoch alle Komponenten testen möchten, die zum Erstellen dieses Blogbeitrags verwendet wurden, stehen sie in unserem Gist-Repository auf GitHub zur Verfügung, einschließlich der NGINX-Unit-Konfiguration zum Bereitstellen der PHP-Seiten:

batch-api.js
katalog.php
inventar.php
bewertung.php
unit.config

Abschluss

Diese Beispiele zeigen, wie API-Anfragen gebündelt und dem Client eine aggregierte Antwort bereitgestellt werden. Der NGINX Plus-Schlüssel-Wert-Speicher ermöglicht es uns, die API-Anfragen dynamisch mit der NGINX Plus-API zu konfigurieren. API-Systeme unterscheiden sich in ihrer genauen Funktionsweise erheblich, daher können an diesem Beispiel viele Verbesserungen vorgenommen werden, um den Anforderungen einer bestimmten API gerecht zu werden.

Sie können mit dem Testen von NGINX JavaScript-Unteranforderungen mit NGINX Open Source beginnen. Wenn Sie jedoch die API-Batchverarbeitungsbeispiele ausprobieren oder andere Anwendungsfälle testen möchten, die die Vorteile der NGINX Plus-Funktionen wie den Schlüssel-Wert-Speicher und die NGINX Plus-API nutzen, fordern Sie eine kostenlose 30-Tage-Testversion an und beginnen Sie mit dem Experimentieren.


„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."