BLOG | NGINX

NGINX Controller API-Verwaltungsmodul vs. Kong: Leistungsvergleich

NGINX-Teil-von-F5-horiz-schwarz-Typ-RGB
Faisal Memon Miniaturbild
Faisal Memon
Veröffentlicht am 06. Mai 2019

Auf dem API-Management-Markt (APIM) herrscht reger Betrieb. Der neueste Gartner Magic Quadrant für Full Life Cycle API Management bewertet 22 Anbieter, davon 7 im Leaders-Quadrant. Um in einem bestehenden Markt wettbewerbsfähig zu sein, ist es erforderlich, eine starke Position aufzubauen, um sich von der Konkurrenz abzuheben und sich zu differenzieren. Was also unterscheidet die API-Management- Lösung von NGINX?

Unser Ziel bei NGINX ist es, leichte und leistungsstarke Software zu entwickeln. NGINX Open Source hat sich zum bevorzugten Webserver für die meistgenutzten Websites der Welt entwickelt, da seine ereignisgesteuerte Architektur besser skalierbar ist als Webserver, die für jede Verbindung einen neuen Prozess oder Thread erzeugen. NGINX Open Source ist zudem das am weitesten verbreitete API-Gateway der Branche, eine Infrastrukturkomponente, die API-Verkehr in APIM-Lösungen wie denen von Apigee, Axway, IBM DataPower, Kong, Red Hat 3scale und Torry Harris verarbeitet.

Das NGINX Controller API Management Module ist eine leistungsstarke APIM-Lösung. In diesem Blog vergleichen wir seine Leistung mit der von Kong, einem Konkurrenten, der für seine hohe Leistung bekannt ist. Kong basiert auf NGINX und verwendet Lua zur Implementierung seiner API-Funktionalität, während das API-Verwaltungsmodul vollständig auf nativen, leistungsstarken Funktionen basiert, die als NGINX Plus-Module implementiert sind. Die API-Verwaltungslösung von NGINX basiert auf einer innovativen Architektur, die die Datenebene und die Kontrollebene entkoppelt. Alle API-Aufrufe werden direkt von NGINX Plus als API-Gateway (Datenebene) abgewickelt, ohne dass eine Interaktion mit der Steuerebene erforderlich ist. Das Ergebnis ist eine leistungsstarke API-Verkehrsvermittlung sowohl für den Nord-Süd- als auch für den Ost-West-Verkehr.

Ein kleiner Vorgeschmack auf die Ergebnisse: Das NGINX Controller API Management Module übertrifft Kong um das Doppelte.

Ein besonderer Dank geht an Intel für die Bereitstellung der Hardware und der Laborfläche für diese Tests. Ausführliche Test- und Hardwaredetails finden Sie im Anhang .

Zu einer einzelnen Anfrage hinzugefügte Latenz

In diesem Test haben wir die zusätzliche Latenz verglichen, die der API-Manager bei einer einzelnen Anfrage für Dateien mit einer Größe von 0 KB und 1 KB verursacht. Wir haben curl verwendet, um die einzelne HTTP-Anfrage ( Details ) zu senden.

Kong erhöht die Latenz im Vergleich zum API-Management-Modul: um 44 % bei einer 0-KB -Datei und um 24 % bei einer 1-KB-Datei.

API-Aufrufe pro Sekunde

Eine Standardmetrik für die HTTP-Skalierbarkeit sind Anfragen pro Sekunde (RPS). Die entsprechende Metrik im Kontext von APIM sind API-Aufrufe pro Sekunde. Wir haben wrk verwendet, um 3 Minuten lang über 300 Verbindungen einen kontinuierlichen Anforderungsstrom für entweder eine 0-KB- oder eine 1-KB- Datei zu senden ( Details ).

Das API-Verwaltungsmodul übertraf Kong und verarbeitete 2,6-mal so viele API-Aufrufe pro Sekunde für 1-KB- Antworten.

CPU-Auslastung

Das API-Verwaltungsmodul führt zu weniger Latenz und verarbeitet mehr API-Aufrufe pro Sekunde als Kong, da es die CPU effizienter nutzt. Wir haben die CPU-Auslastung bei zunehmender Anzahl von API-Aufrufen pro Sekunde gemessen. Da wir nur einen Kern verwendet haben, ist die absolute Anzahl der API-Aufrufe pro Sekunde deutlich geringer als im vorherigen Test, bei dem wir 22 Kerne verwendet haben ( Details ).

Kong erreicht effektiv eine Obergrenze von 5.000 API-Aufrufen pro Sekunde. Bei höheren Anrufvolumina treten merkliche Latenzspitzen auf, was darauf hinweist, dass das System vollständig ausgelastet ist. Bei 5.000 Aufrufen pro Sekunde beträgt die CPU-Auslastung 93 %, also 73 % höher als beim API-Verwaltungsmodul.

API-Aufrufe pro Sekunde mit JWTs

Der abschließende Test misst, wie gut jedes API-Gateway JSON Web Tokens (JWTs) validiert, die bevorzugte Methode zur Authentifizierung von API-Anfragen. Ihre wichtigsten API-Endpunkte werden wahrscheinlich authentifiziert, sodass dieser Test einer realen Konfiguration näher kommt.

Wir haben mit beiden Gateways dasselbe mit HS256 signierte JWT verwendet ( Details ).

Das API-Verwaltungsmodul verarbeitet mehr als doppelt so viele JWT-authentifizierte API-Aufrufe pro Sekunde wie Kong.

So funktioniert der NGINX-Controller

NGINX Controller ist eine Control-Plane-Lösung, die die NGINX Plus-Datenebene verwaltet. Mit dem NGINX Controller können Sie den gesamten Lebenszyklus von NGINX Plus verwalten, als Load Balancer, API-Gateway oder Proxy in einer Service-Mesh-Umgebung. Mit dem API-Verwaltungsmodul des NGINX Controllers können Sie APIs definieren, veröffentlichen, sichern, überwachen und analysieren.

Im Hintergrund generiert der NGINX-Controller eine NGINX-Plus-Konfiguration, die in der zugrunde liegenden NGINX-Plus-Datenebene veröffentlicht wird. Der Kernkonfigurationslader verfügt über einen sehr effizienten Mechanismus zum Speichern von Konfigurationen im Speicher, wodurch das API-Verwaltungsmodul eine hohe Leistung für APIs bereitstellen kann.

Abschluss

Viele Unternehmen nutzen bereits NGINX Open Source als API-Gateway. Capital One konnte durch den Einsatz von NGINX Open Source auf über 12 Milliarden API-Aufrufe pro Tag skalieren. Tatsächlich verwenden viele unserer Konkurrenten, darunter auch Kong, in ihren APIM-Lösungen unter der Haube NGINX Open Source. Unser leichtgewichtiges Design – basierend auf einer nativen, leistungsstarken NGINX-Konfiguration zusammen mit NGINX Plus-Modulen – ermöglicht eine bessere Skalierung des API-Management-Moduls als die von NGINX abgeleitete Konkurrenz.

Die Latenz ist eine der wichtigsten Kennzahlen für das Endbenutzererlebnis. Eine hohe Latenz verringert die Reaktionsfähigkeit der App und frustriert die Benutzer. Das API-Verwaltungsmodul führt im Vergleich zu Kong zu einer um 20–30 % geringeren Latenz bei Benutzeranforderungen. Darüber hinaus nutzt es die Systemressourcen effizienter und benötigt bei gleicher Arbeitslast 40 % weniger CPU-Leistung als Kong.


Anhang

Topologie

Alle Tests wurden mit drei separaten Maschinen durchgeführt, die über 10-GbE-Verbindungen in einem einfachen, flachen Layer-2-Netzwerk verbunden waren.

Verwendete Hardware

Für die Tests wurde folgende Hardware verwendet. Alle drei Maschinen waren identisch. Hyperthreading wurde nicht verwendet. In früheren Tests konnten wir durch Hyperthreading keinen großen Leistungsunterschied feststellen.

CPU Netzwerk Erinnerung
Intel® Xeon(R) CPU E5‑2699 v4 @ 2,20 GHz, 22 Kerne Intel Ethernet-Controller 10‑Gigabit X540‑AT2 128 GB

Verwendete Software

Für die Tests wurde folgende Software verwendet:

  • NGINX Controller API-Verwaltungsmodul Version 2.
  • Kong Open Source, Version 1.0.0. Wir haben Kong Enterprise nicht getestet, aber keine seiner zusätzlichen Funktionen sind für unsere Tests relevant (beispielsweise verwenden Kong Open Source und Kong Enterprise dasselbe JWT-Plugin).
  • Curl -Version 7.61.0.
  • Docker-Version 18.09.1. Um die Verwaltung zu vereinfachen, haben wir sowohl Kong als auch das API-Verwaltungsmodul in Docker-Containern ausgeführt. Wir haben festgestellt, dass Docker die Leistung um etwa 30 % reduziert. Da wir jedoch die relative Leistung vergleichen, überwiegen die Vorteile der Verwendung von Docker die Leistungseinbußen.
  • mpstat in Version 12.0.1 des Systat- Pakets.
  • wrk Version 4.1.0, installiert gemäß dieser Anleitung .

NGINX-Konfiguration

Für die Tests wurde die folgende NGINX-Konfiguration verwendet.

upstream my_upstream { keepalive 60; Server API-Server :80; keepalive_requests 3000000; keepalive_timeout 300; } Server { abhören 8000; access_log aus; keepalive_requests 3000000; keepalive_timeout 300; tcp_nodelay an; Standort /test { setze $apimgmt_environment 4; setze $apimgmt_definition 3; setze $upstream my_upstream; setze $upstream_protocol http; rewrite ^ /_devel_4 zuletzt; } Standort = /_devel_4 { intern; setze $apimgmt_definition_name my_api; setze $apimgmt_environment_name devel; proxy_intercept_errors an; proxy_http_version 1.1; proxy_set_header Verbindung ""; proxy_pass $upstream_protocol://$upstream/0kb; # 0-KB-Datei #proxy_pass $upstream_protocol://$upstream/1kb.bin; # 1-KB-Datei } }

Um die Leistung zu maximieren, haben wir die folgenden Einstellungen vorgenommen. Wie im nächsten Abschnitt beschrieben, haben wir ähnliche Einstellungen in der Kong-Konfiguration vorgenommen.

  • keepalive_requests und keepalive_timeout wurden auf einen hohen Wert eingestellt, um den Overhead beim Einrichten von TCP-Verbindungen zu minimieren.
  • tcp_nodelay wurde aktiviert, wodurch die Leistung durch Deaktivierung des Nagle-Algorithmus leicht verbessert wurde.
  • access_log wurde deaktiviert. Durch die Aktivierung verringert sich die Leistung um etwa 10 %.
  • Wir haben die beiden Proxy_Pass- Direktiven verwendet, um die entsprechende Dateigröße anzufordern.

Kong-Konfiguration

Wir haben die folgenden Konfigurationsdirektiven zu kong.conf.default hinzugefügt, entsprechend den Einstellungen in der NGINX-Konfiguration, die im vorherigen Abschnitt besprochen wurden.

nginx_http_tcp_nodelay=einnginx_http_keepalive_requests=3000000
nginx_http_keepalive_timeout=300
proxy_access_log=aus

Wir haben die folgenden Kong-API-Aufrufe ausgeführt, um eine Route zum API-Server zu erstellen. Der erste Befehl erstellt einen Dienst namens „Test“ und der zweite erstellt die Route /test, die auf den Server verweist.

$ curl -X POST http://localhost:8001/services/ \ --data 'name=test' \ --data 'url=http:// API-server :80/0kb' $ curl -X POST http://localhost:8001/services/test/routes \ --data 'paths[]=/test'

Die folgenden Befehle zeigen die Konfiguration des Dienstes bzw. der Route an. Wir leiten die Ausgabe an das JQ -Tool weiter, um das Lesen der JSON-Ausgabe zu erleichtern.

$ curl localhost:8001/services/ | jq '.' { "next": null, "data": [ { "host": "172.20.40.32", "erstellt am": 1556770191, "Verbindungszeitüberschreitung": 60000, "id": "f4629d56-550b-4b37-aa59-66d931aa6f37", "Protokoll": "http", "Name": "Test", "Lesezeitüberschreitung": 60000, "Hafen": 80, "Pfad": "/0kb", "aktualisiert_am": 1556770191, „Wiederholungsversuche“: 5, „Schreibzeitüberschreitung“: 60000 } ] } $ curl localhost:8001/services/test/routes | jq '.' { "next": null, "data": [ { "created_at": 1556770191, "Methoden": null, "ID": "a7b417af-ccd4-48f7-b787-ae19490194dc", "Dienst": { "ID": "f4629d56-550b-4b37-aa59-66d931aa6f37" }, "Name": null, "Hosts": null, "aktualisiert am": 1556770191, "preserve_host": falsch, "regex_priority": 0, "Pfade": [ "/test" ], "Quellen": null, "Ziele": null, "snis": null, "Protokolle": [ "http", "https" ], "strip_path": true } ] }

Testmethodik

Zu einer einzelnen Anfrage hinzugefügte Latenz

Für den Latenztest einzelner Anfragen haben wir curl verwendet. Um eine Basislinie festzulegen, haben wir zunächst eine Anfrage an den API-Server gestellt, ohne dass ein API-Gateway davor geschaltet war. Anschließend haben wir bei jedem API-Gateway vor dem API-Server dieselbe Anfrage gestellt, um die dadurch verursachte Latenz zu messen.

$ curl -w "@curl-latency.txt" -o /dev/null -s http:// Zielserver

Der Inhalt von curl-latency.txt :

    time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
----------\n
time_total: %{time_total}\n

Das Diagramm in „Zu einer einzelnen Anforderung hinzugefügte Latenz“ zeigt die Gesamtzeit in Millisekunden. Hier ist eine Beispielausgabe:

$ curl -w "@curl-latency.txt" -o /dev/null -s http://192.0.2.1/API-Endpunkt Zeitnamenssuche:  0,000035 Verbindungszeit:  0,000364 Zeit_App-Verbindung:  0,000000 Zeit_Vorübertragung:  0,000401 Zeitumleitung:  0.000000 Zeit_Startübertragung:  0,001701 ---------- Gesamtzeit:  0,001727

API-Aufrufe pro Sekunde

Wir haben die API-Aufrufe pro Sekunde mit wrk getestet, einem skalierbaren Benchmarking-Tool, das wir häufig verwenden. Wir haben verschiedene Parameterkombinationen ausprobiert und diese hat die Leistung sowohl für das API-Verwaltungsmodul als auch für Kong maximiert:

$ wrk -t 22 -c 300 -d 180 http:// Zielserver

Der Befehl erstellt 22 Wrk -Threads (1 pro Kern) und insgesamt 300 Verbindungen zwischen den Threads. Der Parameter -d gibt die Dauer des Tests an, in unserem Fall 180 Sekunden (3 Minuten). Beispielausgabe:

$ wrk -t 22 -c 300 -d 180 http://192.0.2.1/api-endpoint 3-Minuten-Test wird ausgeführt @ http://192.0.2.1/api-endpoint 22 Threads und 300 Verbindungen Thread-Statistiken Durchschnittliche Standardabweichung Max. +/- Standardabweichung Latenz 13,96 ms 7,84 ms 279,85 ms 77,37 % Anf./Sek. 0,96 k 298,23 1,88 k 68,55 % 3769861 Anfragen in 3,00 m, 36,25 GB Lesezugriff Anfragen/Sek.:  20934,34 Übertragungen/Sek.:    206,16 MB

CPU-Auslastung

Wir haben die CPU-Auslastung mit mpstat (einem Standard-Linux-Tool für diesen Zweck) getestet, während wir den Befehl wrk für API-Aufrufe pro Sekunde ausgeführt haben. Beispielausgabe (zur besseren Lesbarkeit auf zwei Zeilen verteilt):

$ mpstat Linux 4.18.0-13-generic (nbdw38) 29.04.2019 _x86_64_ (88 CPU) 15:34:50 Uhr CPU %usr %nice %sys %iowait %irq %soft %steal ...
15:34:50 Uhr alle 0,04 0,00 0,02 0,00 0,00 0,03 0,00 ... ... %Gast %gnice %Leerlauf ...   0,00 0,00 99,91

API-Aufrufe pro Sekunde mit JWTs

Wir haben die JWT-Leistung mit dem Befehl wrk für API-Aufrufe pro Sekunde getestet, mit dem zusätzlichen Parameter -H , um das JWT in die Autorisierung einzufügen: Träger- HTTP-Header. Wir haben die JWT- und JSON-Webschlüssel (JWKs) gemäß den Anweisungen in diesem Blogbeitrag generiert und das JWT in einer Datei mit dem Namen test.jwt gespeichert.

$ wrk -t 22 -c 300 -d 180 -H „Autorisierung: Träger `cat test.jwt`" \ http:// Zielserver

„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."