BLOG | NGINX

Module de gestion des API du contrôleur NGINX vs. Kong: Comparaison des performances

NGINX-Partie-de-F5-horiz-black-type-RGB
Vignette de Faisal Memon
Fayçal Memon
Publié le 6 mai 2019

Le marché de la gestion des API (APIM) est un espace encombré. Le dernier Magic Quadrant de Gartner pour la gestion du cycle de vie complet des API classe 22 fournisseurs, dont 7 dans le quadrant des leaders. Être compétitif sur un marché existant nécessite d’établir une position forte pour se différencier et se démarquer de la concurrence. Alors, qu’est-ce qui rend la solution de gestion des API de NGINX différente ?

Chez NGINX, notre objectif est de créer des logiciels légers et performants. NGINX Open Source est devenu le serveur Web de référence pour les sites les plus fréquentés au monde, car son architecture pilotée par événements s'adapte mieux que les serveurs Web qui génèrent un processus ou un thread pour chaque connexion. NGINX Open Source est également la passerelle API la plus répandue du secteur, un composant d'infrastructure qui traite le trafic API dans les solutions APIM telles que celles d'Apigee, Axway, IBM DataPower, Kong, Red Hat 3scale et Torry Harris.

Le module de gestion des API du contrôleur NGINX est une solution APIM hautes performances. Dans ce blog, nous comparerons ses performances à celles de Kong, un concurrent connu pour ses hautes performances. Kong est construit sur NGINX et utilise Lua pour implémenter ses fonctionnalités API, tandis que le module de gestion des API s'appuie entièrement sur des fonctionnalités natives hautes performances implémentées en tant que modules NGINX Plus. La solution de gestion des API de NGINX repose sur une architecture innovante qui dissocie le plan de données et le plan de contrôle. Tous les appels API sont gérés directement par NGINX Plus agissant comme passerelle API (plan de données) sans nécessiter aucune interaction avec le plan de contrôle. Il en résulte une médiation du trafic API hautes performances pour le trafic nord-sud et est-ouest.

Un aperçu des résultats : le module de gestion des API du contrôleur NGINX surpasse Kong de 2 fois.

Un merci spécial à Intel pour avoir fourni le matériel et l'espace de laboratoire utilisé pour effectuer ces tests. Les détails complets des tests et du matériel peuvent être trouvés dans l' annexe .

Latence ajoutée à une seule requête

Dans ce test, nous avons comparé la latence supplémentaire introduite par le gestionnaire d'API pour une seule requête, pour des fichiers de 0 Ko et 1 Ko . Nous avons utilisé curl pour envoyer la requête HTTP unique ( détails ).

Kong augmente la latence par rapport au module de gestion des API : de 44 % pour un fichier de 0 Ko et de 24 % pour un fichier de 1 Ko.

Appels API par seconde

Une mesure standard d'évolutivité HTTP est le nombre de requêtes par seconde (RPS). La métrique équivalente dans le contexte d'APIM est le nombre d'appels API par seconde. Nous avons utilisé wrk pour envoyer un flux continu de requêtes pour un fichier de 0 Ko ou de 1 Ko , sur 300 connexions pendant 3 minutes ( détails ).

Le module de gestion des API a surpassé Kong, gérant 2,6 fois plus d'appels d'API par seconde pour des réponses de 1 Ko .

Utilisation du processeur

Le module de gestion des API introduit moins de latence et gère plus d'appels d'API par seconde que Kong car il utilise le processeur plus efficacement. Nous avons mesuré l’utilisation du processeur à un nombre croissant d’appels d’API par seconde. Nous avons utilisé un seul cœur, donc le nombre absolu d’appels d’API par seconde est bien inférieur à celui du test précédent, où nous avons utilisé 22 cœurs ( détails ).

Kong plafonne effectivement à 5 000 appels API par seconde – la latence augmente sensiblement à des volumes d'appels supérieurs à ce niveau, indiquant que le système est complètement chargé. À 5 000 appels par seconde, l'utilisation du processeur est de 93 %, soit 73 % supérieure à celle du module de gestion des API.

Appels API par seconde avec JWT

Le test final mesure dans quelle mesure chaque passerelle API valide les jetons Web JSON (JWT), la méthode préférée pour authentifier les requêtes API. Vos points de terminaison API les plus importants seront probablement authentifiés, ce test se rapproche donc davantage d’une configuration réelle.

Nous avons utilisé le même JWT, signé via HS256, avec les deux passerelles ( détails ).

Le module de gestion des API gère plus de 2 fois plus d'appels d'API authentifiés JWT par seconde que Kong.

Comment fonctionne le contrôleur NGINX

NGINX Controller est une solution de plan de contrôle qui gère le plan de données NGINX Plus. NGINX Controller vous permet de gérer l'intégralité du cycle de vie de NGINX Plus, en tant qu'équilibreur de charge, passerelle API ou proxy dans un environnement de maillage de services. Avec le module de gestion des API de NGINX Controller, vous pouvez définir, publier, sécuriser, surveiller et analyser les API.

Sous le capot, NGINX Controller génère une configuration NGINX Plus qui est publiée sur le plan de données NGINX Plus sous-jacent. Le chargeur de configuration principal dispose d'un mécanisme très efficace pour stocker les configurations en mémoire, permettant au module de gestion des API de fournir des performances élevées pour les API.

Conclusion

De nombreuses entreprises utilisent déjà NGINX Open Source comme passerelle API. Capital One a pu évoluer vers plus de 12 milliards d'appels API par jour grâce à NGINX Open Source. En fait, bon nombre de nos concurrents, dont Kong, utilisent NGINX Open Source en arrière-plan de leurs solutions APIM. Notre conception légère, basée sur une configuration NGINX native et hautes performances ainsi que sur des modules NGINX Plus, permet au module de gestion des API d'évoluer mieux que la concurrence dérivée de NGINX.

La latence est l’une des mesures les plus importantes de l’expérience de l’utilisateur final. Une latence élevée réduit la réactivité des applications, ce qui frustre les utilisateurs. Le module de gestion des API ajoute 20 à 30 % de latence en moins aux requêtes des utilisateurs par rapport à Kong. Il utilise également les ressources système plus efficacement, en utilisant 40 % de CPU en moins que Kong pour la même charge de travail.


Appendice

Topologie

Tous les tests ont été effectués à l’aide de trois machines distinctes connectées par des liaisons 10 GbE dans un réseau de couche 2 simple et plat.

Matériel utilisé

Le matériel suivant a été utilisé pour les tests. Les trois machines étaient identiques. L'hyperthreading n'a pas été utilisé. Lors des tests précédents, nous n’avons pas observé de différence majeure dans les performances de l’hyperthreading.

Processeur Réseau Mémoire
Processeur Intel® Xeon(R) E5-2699 v4 à 2,20 GHz, 22 cœurs Contrôleur Ethernet Intel 10 Gigabit X540-AT2 128 Go

Logiciels utilisés

Le logiciel suivant a été utilisé pour effectuer les tests :

  • Module de gestion des API du contrôleur NGINX version 2.
  • Version Open Source de Kong 1.0.0. Nous n’avons pas testé Kong Enterprise, mais aucune de ses fonctionnalités supplémentaires n’est pertinente pour nos tests (par exemple, Kong Open Source et Kong Enterprise utilisent le même plug-in JWT).
  • version curl 7.61.0.
  • Version Docker 18.09.1. Pour faciliter la gestion, nous avons exécuté Kong et le module de gestion des API dans les conteneurs Docker. Nous avons constaté que Docker réduit les performances d’environ 30 %, mais comme nous comparons les performances relatives, les avantages de l’utilisation de Docker l’emportent sur la perte de performances.
  • mpstat dans la version 12.0.1 du paquet systat .
  • version wrk 4.1.0, installée selon ces instructions .

Configuration NGINX

La configuration NGINX suivante a été utilisée pour les tests.

en amont mon_en amont { keepalive 60; serveur API-serveur :80; keepalive_requests 3000000; keepalive_timeout 300; } serveur { écouter 8000; access_log désactivé; keepalive_requests 3000000; keepalive_timeout 300; tcp_nodelay activé; emplacement /test { définir $apimgmt_environment 4; définir $apimgmt_definition 3; définir $upstream mon_en amont; définir $upstream_protocol http; réécrire ^ /_devel_4 dernier; } emplacement = /_devel_4 { interne; définir $apimgmt_definition_name mon_api; définir $apimgmt_environment_name devel; proxy_intercept_errors activé; proxy_http_version 1.1; proxy_set_header Connexion ""; proxy_pass $upstream_protocol://$upstream/0kb; # fichier de 0 Ko #proxy_pass $upstream_protocol://$upstream/1kb.bin; # fichier de 1 Ko } }

Nous avons effectué les réglages suivants pour optimiser les performances. Comme détaillé dans la section suivante, nous avons effectué des réglages similaires dans la configuration Kong.

  • keepalive_requests et keepalive_timeout ont été définis sur un nombre élevé pour minimiser la surcharge liée à la configuration des connexions TCP.
  • tcp_nodelay a été activé, améliorant légèrement les performances en désactivant l'algorithme de Nagle.
  • access_log a été désactivé. L'activer réduit les performances d'environ 10 %.
  • Nous avons utilisé les deux directives proxy_pass pour demander la taille de fichier appropriée.

Configuration de Kong

Nous avons ajouté les directives de configuration suivantes à kong.conf.default , correspondant aux paramètres de la configuration NGINX décrits dans la section précédente.

nginx_http_tcp_nodelay=onnginx_http_keepalive_requests=3000000
nginx_http_keepalive_timeout=300
proxy_access_log=off

Nous avons exécuté les appels d’API Kong suivants pour créer une route vers le serveur API. La première commande crée un service nommé test et la seconde crée la route /test pointant vers le serveur.

$ 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'

Les commandes suivantes affichent respectivement la configuration du service et de l'itinéraire. Nous transmettons la sortie à l’outil jq pour faciliter la lecture de la sortie JSON.

$ curl localhost:8001/services/ | jq '.' { "suivant": null, "données": [ { "hôte": "172.20.40.32", "créé à": 1556770191, « connect_timeout » : 60000, "id": "f4629d56-550b-4b37-aa59-66d931aa6f37", "protocole": "http", "nom": "test", "read_timeout": 60000, "port": 80, "chemin": "/0kb", "mis à jour à": 1556770191, « nouvelles tentatives » : 5, « write_timeout » : 60000 } ] } $ curl localhost:8001/services/test/routes | jq '.' { "suivant": null, "données": [ { "créé_à": 1556770191, « méthodes » : null, « id » : « a7b417af-ccd4-48f7-b787-ae19490194dc », « service » : { « id » : « f4629d56-550b-4b37-aa59-66d931aa6f37 » }, « nom » : null, « hôtes » : null, « mis à jour à » : 1556770191, « preserve_host » : faux, « regex_priority » : 0, "chemins" : [ "/test" ], "sources" : nulle, "destinations" : nulle, "snis" : nulle, "protocoles" : [ "http", "https" ], "strip_path" : vrai } ] }

Méthodologie de test

Latence ajoutée à une seule requête

Nous avons utilisé curl pour les tests de latence des requêtes uniques. Pour définir une ligne de base, nous avons d’abord effectué une demande au serveur API sans passerelle API devant lui. Nous avons ensuite effectué la même requête auprès de chaque passerelle API devant le serveur API pour mesurer la latence qu'elles introduisaient.

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

Le contenu de 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

Le graphique de la latence ajoutée à une seule requête affiche time_total , en millisecondes. Voici un exemple de sortie :

$ curl -w "@curl-latency.txt" -o /dev/null -s http://192.0.2.1/api-endpoint heure_nomrecherche :  0,000035 heure_de_connexion :  0,000364 heure_appconnect :  0,000000 heure_pré-transfert :  0,000401 heure_de_redirection :  0,000000 heure_début_transfert :  0,001701 ---------- temps_total:  0,001727

Appels API par seconde

Nous avons testé les appels API par seconde avec wrk , un outil d'analyse comparative évolutif que nous utilisons souvent. Nous avons essayé différentes combinaisons de paramètres, et celle-ci a maximisé les performances du module de gestion des API et de Kong :

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

La commande crée 22 threads wrk (1 par cœur) et un total de 300 connexions entre les threads. Le paramètre -d spécifie la durée du test, dans notre cas 180 secondes (3 minutes). Exemple de sortie :

$ wrk -t 22 -c 300 -d 180 http://192.0.2.1/api-endpoint Exécution du test 3m sur http://192.0.2.1/api-endpoint 22 threads et 300 connexions Statistiques des threads Moyenne Écart-type Max +/- Écart-type Latence 13,96 ms 7,84 ms 279,85 ms 77,37 % Req/s 0,96 k 298,23 1,88 k 68,55 % 3 769 861 requêtes en 3,00 m, 36,25 Go de lecture Requêtes/s :  20934,34 Transfert/sec :    206,16 Mo

Utilisation du processeur

Nous avons testé l'utilisation du processeur avec mpstat (un outil Linux standard à cet effet) lors de l'exécution de la commande wrk pour les appels API par seconde. Exemple de sortie (réparti sur deux lignes pour plus de lisibilité) :

$ mpstat Linux 4.18.0-13-generic (nbdw38) 29/04/2019 _x86_64_ (88 CPU) 15:34:50 CPU %usr %nice %sys %iowait %irq %soft %steal ...
15:34:50 PM tous 0,04 0,00 0,02 0,00 0,00 0,03 0,00 ... ... %invité %gnice %idle ...   0,00 0,00 99,91

Appels API par seconde avec JWT

Nous avons testé les performances du JWT avec la commande wrk pour les appels d'API par seconde, avec l'ajout du paramètre -H pour insérer le JWT dans l' autorisation : Porteur En-tête HTTP. Nous avons généré les clés Web JWT et JSON (JWK) en suivant les instructions de cet article de blog , en stockant le JWT dans un fichier nommé test.jwt .

$ wrk -t 22 -c 300 -d 180 -H "Autorisation : Porteur `cat test.jwt`" \ http:// serveur-cible

« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."