El mercado de gestión de API (APIM) es un espacio abarrotado. El último Cuadrante Mágico de Gartner para la gestión de API de ciclo de vida completo clasifica a 22 proveedores, 7 de ellos en el cuadrante de líderes. Competir en un mercado existente requiere establecer una posición sólida para diferenciarse y destacarse de la competencia. Entonces, ¿qué hace que la solución de gestión de API de NGINX sea diferente?
En NGINX nuestro objetivo es crear software liviano y de alto rendimiento. NGINX Open Source se ha convertido en el servidor web de referencia para los sitios más activos del mundo porque su arquitectura basada en eventos escala mejor que los servidores web que generan un proceso o hilo para cada conexión. NGINX Open Source es también la puerta de enlace API más omnipresente de la industria, un componente de infraestructura que procesa el tráfico de API en soluciones APIM como las de Apigee, Axway, IBM DataPower, Kong, Red Hat 3scale y Torry Harris.
El módulo de gestión de API del controlador NGINX es una solución APIM de alto rendimiento. En este blog compararemos su rendimiento con el de Kong, un competidor conocido por su alto rendimiento. Kong está construido sobre NGINX y utiliza Lua para implementar su funcionalidad API, mientras que el módulo de administración de API se basa completamente en capacidades nativas de alto rendimiento que se implementan como módulos NGINX Plus. La solución de gestión de API de NGINX está construida sobre una arquitectura innovadora que desacopla el plano de datos y el plano de control. Todas las llamadas API son manejadas directamente por NGINX Plus, actuando como puerta de enlace API (plano de datos) sin requerir ninguna interacción con el plano de control. Esto da como resultado una mediación de tráfico API de alto rendimiento tanto para el tráfico norte-sur como para el este-oeste.
Un adelanto de los resultados: el módulo de gestión de API del controlador NGINX supera a Kong en 2x.
Un agradecimiento especial a Intel por proporcionar el hardware y el espacio de laboratorio utilizados para realizar estas pruebas. Los detalles completos de las pruebas y del hardware se pueden encontrar en el Apéndice .
En esta prueba comparamos la latencia adicional introducida por el administrador de API en una sola solicitud, para archivos de 0 KB y 1 KB de tamaño. Usamos curl
para enviar la única solicitud HTTP ( detalles ).
Kong aumenta la latencia en comparación con el módulo de gestión de API: en un 44 % para un archivo de 0 KB y en un 24 % para un archivo de 1 KB.
Una métrica de escalabilidad HTTP estándar son las solicitudes por segundo (RPS). La métrica equivalente en el contexto de APIM son las llamadas API por segundo. Usamos wrk
para enviar un flujo continuo de solicitudes de archivos de 0 KB o 1 KB , en 300 conexiones durante 3 minutos ( detalles ).
El módulo de administración de API superó a Kong: manejó 2,6 veces más llamadas de API por segundo para respuestas de 1 KB .
El módulo de administración de API introduce menos latencia y maneja más llamadas de API por segundo que Kong porque utiliza la CPU de manera más eficiente. Medimos el uso de la CPU en cantidades crecientes de llamadas API por segundo. Utilizamos un solo núcleo, por lo que el número absoluto de llamadas API por segundo es mucho menor que en la prueba anterior, donde utilizamos 22 núcleos ( detalles ).
Kong efectivamente tiene un límite de 5000 llamadas API por segundo: la latencia aumenta notablemente con volúmenes de llamadas superiores a ese, lo que indica que el sistema está completamente cargado. Con 5000 llamadas por segundo, el uso de la CPU es del 93 %, un 73 % más alto que el módulo de administración de API.
La prueba final mide qué tan bien cada puerta de enlace API valida los tokens web JSON (JWT), el método preferido para autenticar solicitudes de API. Es probable que sus puntos finales de API más importantes estén autenticados, por lo que esta prueba se aproxima más a una configuración del mundo real.
Utilizamos el mismo JWT, firmado con HS256, con ambas pasarelas ( detalles ).
El módulo de administración de API maneja más del doble de llamadas API autenticadas mediante JWT por segundo que Kong.
NGINX Controller es una solución de plano de control que administra el plano de datos NGINX Plus. El controlador NGINX le permite administrar todo el ciclo de vida de NGINX Plus, como un balanceador de carga, una puerta de enlace API o un proxy en un entorno de malla de servicios. Con el módulo de gestión de API del controlador NGINX, puede definir, publicar, proteger, supervisar y analizar API.
Bajo el capó, NGINX Controller genera la configuración de NGINX Plus que se publica en el plano de datos NGINX Plus subyacente. El cargador de configuración principal tiene un mecanismo muy eficiente para almacenar configuraciones en la memoria, lo que permite que el módulo de administración de API ofrezca un alto rendimiento para las API.
Muchas empresas ya utilizan NGINX Open Source como su puerta de enlace API. Capital One ha podido escalar a más de 12 mil millones de llamadas API por día utilizando NGINX Open Source. De hecho, muchos de nuestros competidores, incluido Kong, utilizan NGINX Open Source en sus soluciones APIM. Nuestro diseño liviano, basado en la configuración nativa de NGINX de alto rendimiento junto con los módulos NGINX Plus, permite que el módulo de administración de API se escale mejor que la competencia derivada de NGINX.
La latencia es una de las métricas más importantes para la experiencia del usuario final. La alta latencia reduce la capacidad de respuesta de la aplicación, frustrando a los usuarios. El módulo de gestión de API agrega entre un 20 % y un 30 % menos de latencia a las solicitudes de los usuarios en comparación con Kong. También utiliza los recursos del sistema de manera más eficiente, utilizando un 40% menos de CPU que Kong para la misma carga de trabajo.
Todas las pruebas se realizaron utilizando tres máquinas separadas conectadas por enlaces de 10 GbE en una red de capa 2 simple y plana.
Para la prueba se utilizó el siguiente hardware. Las tres máquinas eran idénticas. No se utilizó hyperthreading. En pruebas anteriores no observamos una diferencia importante en el rendimiento del hyperthreading.
CPU | Red | Memoria |
---|---|---|
CPU Intel® Xeon(R) E5‑2699 v4 a 2,20 GHz, 22 núcleos | Controlador Ethernet Intel 10‑Gigabit X540‑AT2 | 128 GB |
Para realizar las pruebas se utilizó el siguiente software:
curl
versión 7.61.0.mpstat
en la versión 12.0.1 del paquete systat
.wrk
versión 4.1.0, instalada según estas instrucciones .Se utilizó la siguiente configuración de NGINX para la prueba.
upstream my_upstream { keepalive 60; servidor API-server :80; keepalive_requests 3000000; keepalive_timeout 300; } servidor { escuchar 8000; acceso_cerrar sesión; keepalive_requests 3000000; keepalive_timeout 300; tcp_nodelay activado; ubicación /prueba { establecer $apimgmt_environment 4; establecer $apimgmt_definition 3; establecer $upstream my_upstream; establecer $upstream_protocol http; reescribir ^ /_devel_4 último; } ubicación = /_devel_4 { interno; establecer $apimgmt_definition_name my_api; establecer $apimgmt_environment_name devel; proxy_intercept_errors activado; proxy_http_version 1.1; proxy_set_header Conexión ""; proxy_pass $upstream_protocol://$upstream/0kb; # archivo de 0 KB #proxy_pass $upstream_protocol://$upstream/1kb.bin; # archivo de 1 KB } }
Realizamos las siguientes configuraciones para maximizar el rendimiento. Como se detalla en la siguiente sección, realizamos configuraciones similares en la configuración de Kong.
keepalive_requests
y keepalive_timeout
se establecieron en un número alto para minimizar la sobrecarga derivada de la configuración de conexiones TCP.tcp_nodelay
, mejorando levemente el rendimiento al deshabilitar el algoritmo de Nagle.access_log
fue deshabilitado. Habilitarlo reduce el rendimiento en aproximadamente un 10%.proxy_pass
para solicitar el tamaño de archivo apropiado.Agregamos las siguientes directivas de configuración a kong.conf.default , que coinciden con las configuraciones de la configuración de NGINX analizada en la sección anterior.
Retardo de nodo TCP de nginx_http=activado Solicitudes de mantenimiento de nginx_http=3000000
Tiempo de espera de mantenimiento de nginx_http=300
Registro de acceso al proxy=desactivado
Ejecutamos las siguientes llamadas a la API de Kong para crear una ruta al servidor API. El primer comando crea un servicio llamado test y el segundo crea la ruta /test que apunta al servidor.
$ curl -X POST http://localhost:8001/servicios/ \ --data 'nombre=prueba' \ --data 'url=http:// API-servidor :80/0kb' $ curl -X POST http://localhost:8001/servicios/prueba/rutas \ --data 'rutas[]=/prueba'
Los siguientes comandos muestran la configuración del servicio y la ruta, respectivamente. Canalizamos la salida a la herramienta jq para facilitar la lectura de la salida JSON.
$ curl localhost:8001/servicios/ | jq '.' { "siguiente": null, "datos": [ { "host": "172.20.40.32", "creado_en": 1556770191, "tiempo de espera de conexión": 60000, "id": "f4629d56-550b-4b37-aa59-66d931aa6f37", "protocolo": "http", "nombre": "prueba", "tiempo de espera de lectura": 60000, "puerto": 80, "ruta": "/0kb", "actualizado_en": 1556770191, "reintentos": 5, "tiempo de espera de escritura": 60000 } ] } $ curl localhost:8001/servicios/prueba/rutas | jq '.' { "siguiente": null, "datos": [ { "creado_en": 1556770191, "métodos": nulo, "id": "a7b417af-ccd4-48f7-b787-ae19490194dc", "servicio": { "id": "f4629d56-550b-4b37-aa59-66d931aa6f37" }, "nombre": nulo, "hosts": nulo, "actualizado_en": 1556770191, "preserve_host": falso, "regex_priority": 0, "rutas": [ "/prueba" ], "orígenes": nulo, "destinos": nulo, "snis": nulo, "protocolos": [ "http", "https" ], "strip_path": verdadero } ] }
Utilizamos curl
para la prueba de latencia de solicitud única. Para establecer una línea base, primero hicimos una solicitud al servidor API sin una puerta de enlace API delante. Luego hicimos la misma solicitud con cada puerta de enlace API frente al servidor API para medir la latencia que introdujeron.
$ curl -w "@curl-latency.txt" -o /dev/null -s http:// servidor-destino
El contenido de curl-latency.txt :
Búsqueda_de_nombre_tiempo: %{Búsqueda_de_nombre_tiempo}\n
Conexión_tiempo: %{Conexión_tiempo}\n
Conexión_aplicación_tiempo: %{Conexión_aplicación_tiempo}\n
Pretransferencia_tiempo: %{Pretransferencia_tiempo}\n
Redirección_tiempo: %{Redirección_tiempo}\n
Inicio_transferencia_tiempo: %{Inicio_transferencia_tiempo}\n
----------\n
Total_tiempo: %{Total_tiempo}\n
El gráfico de Latencia agregada a una sola solicitud muestra time_total
, en milisegundos. A continuación se muestra un ejemplo de salida:
$ curl -w "@curl-latency.txt" -o /dev/null -s http://192.0.2.1/api-endpoint búsqueda_de_nombre_de_hora: 0.000035 tiempo_conexión: 0.000364 tiempo_appconnect: 0.000000 tiempo_pretransferencia: 0.000401 tiempo_redireccionamiento: 0.000000 tiempo_iniciar transferencia: 0.001701 ---------- tiempo_total: 0.001727
Probamos las llamadas API por segundo con wrk
, una herramienta de evaluación comparativa escalable que utilizamos a menudo. Probamos varias combinaciones de parámetros y esta maximizó el rendimiento tanto del módulo de administración de API como de Kong:
$ wrk -t 22 -c 300 -d 180 http:// servidor-de-destino
El comando crea 22 subprocesos wrk
(1 por núcleo) y un total de 300 conexiones entre los subprocesos. El parámetro -d
especifica la duración de la prueba, en nuestro caso 180 segundos (3 minutos). Ejemplo de salida:
$ wrk -t 22 -c 300 -d 180 http://192.0.2.1/api-endpoint Ejecutando prueba de 3 m en http://192.0.2.1/api-endpoint 22 subprocesos y 300 conexiones Estadísticas de subprocesos Desviación estándar promedio Desviación estándar máxima +/- Latencia 13,96 ms 7,84 ms 279,85 ms 77,37 % Solicitudes/seg 0,96 k 298,23 1,88 k 68,55 % 3769861 solicitudes en 3,00 m, 36,25 GB de lectura Solicitudes/seg: 20934.34 Transferencia/seg: 206,16 MB
Probamos el uso de la CPU con mpstat
(una herramienta estándar de Linux para ese propósito) mientras ejecutábamos el comando wrk
para llamadas API por segundo. Ejemplo de salida (distribuido en dos líneas para facilitar la legibilidad):
$ 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 todos 0.04 0.00 0.02 0.00 0.00 0.03 0.00 ... ... %guest %gnice %idle ... 0.00 0.00 99.91
Probamos el rendimiento de JWT con el comando wrk
para llamadas API por segundo, con la adición del parámetro -H
para insertar el JWT en la Autorización:
Portador
Encabezado HTTP. Generamos las claves web JWT y JSON (JWKs) siguiendo las instrucciones de esta publicación de blog y almacenamos las JWT en un archivo llamado test.jwt .
$ wrk -t 22 -c 300 -d 180 -H "Autorización: Portador `cat test.jwt`" \ http:// servidor-objetivo
"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.