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 .
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.
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 .
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.
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.
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.
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.
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.
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 |
Le logiciel suivant a été utilisé pour effectuer les tests :
curl
7.61.0.mpstat
dans la version 12.0.1 du paquet systat
.wrk
4.1.0, installée selon ces instructions .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 %.proxy_pass
pour demander la taille de fichier appropriée.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 } ] }
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
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
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
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."