
Uso de variables para la gestión del rendimiento de aplicaciones
Las variables son un aspecto importante de la configuración de NGINX que a veces se pasa por alto. Con aproximadamente 150 variables disponibles, existen variables para mejorar cada parte de la configuración. En esta entrada del blog explicamos cómo utilizar las variables de NGINX para el seguimiento de aplicaciones y la gestión del rendimiento de aplicaciones (APM), centrándonos en detectar cuellos de botella en el rendimiento de la aplicación. Esta entrada se aplica tanto a NGINX Open Source como a NGINX Plus. Para abreviar, nos referiremos a NGINX Plus en todo el texto, salvo cuando haya alguna diferencia entre ambas versiones.
El entorno de entrega de aplicaciones
En nuestro entorno de ejemplo de entrega de aplicaciones, NGINX Plus funciona como proxy inverso para nuestra aplicación. La aplicación consta de un frontend web tras el que se encuentran varios microservicios.

Seguimiento de solicitudes de extremo a extremo
NGINX Plus R10 (y NGINX 1.11.0) incorpora la variable $request_id, que es una cadena de 32 caracteres hexadecimales generada aleatoriamente y asignada de forma automática a cada solicitud HTTP cuando llega (por ejemplo, 444535f9378a3dfa1b8604bc9e05a303). Este mecanismo aparentemente sencillo proporciona una potente herramienta de seguimiento y resolución de problemas. Si configura NGINX Plus y todos los servicios de backend para que transmitan el valor de $request_id, podrá realizar un seguimiento integral de cada solicitud. Esta configuración de ejemplo corresponde a nuestro servidor NGINX Plus de frontend.
upstream app_server { server 10.0.0.1:80;
}
server {
listen 80;
add_header X-Request-ID $request_id; # Return to client
location / {
proxy_pass http://app_server;
proxy_set_header X-Request-ID $request_id; # Pass to app server
}
}Para configurar NGINX Plus para el seguimiento de solicitudes, primero definimos la ubicación de red del servidor de aplicaciones en el bloque upstream. Para simplificar, aquí solo mostramos un único server de aplicaciones, aunque normalmente utilizaríamos varios para garantizar una alta disponibilidad y equilibrar la carga.
El bloque server de la aplicación define cómo gestiona NGINX Plus las solicitudes HTTP entrantes. La directiva listen indica a NGINX Plus que escuche en el puerto 80, el predeterminado para el tráfico HTTP, pero una configuración de producción normalmente debe usar SSL/TLS para proteger los datos en tránsito.
La directiva add_header devuelve al cliente el valor $request_id como una cabecera personalizada en la respuesta. Esto resulta útil para realizar pruebas y también para aplicaciones cliente que generan sus propios registros, como las aplicaciones móviles, ya que permite relacionar con precisión un error del lado del cliente con los registros del servidor.
Por último, el bloque location se aplica a todo el espacio de la aplicación (/) y la directiva proxy_pass simplemente reenvía todas las solicitudes al servidor de aplicaciones. La directiva proxy_set_header modifica la solicitud reenviada añadiendo una cabecera HTTP que se pasa a la aplicación. En este caso, creamos una nueva cabecera denominada X-Request-ID y le asignamos el valor de la variable $request_id. De este modo, nuestra aplicación recibe el ID de solicitud generado por NGINX Plus.
Registro de $request_id de extremo a extremo
Nuestro objetivo con el seguimiento de aplicaciones es identificar los cuellos de botella de rendimiento en el ciclo de vida del procesamiento de solicitudes como parte de la gestión del rendimiento de las aplicaciones. Para ello, registramos los eventos relevantes durante el procesamiento, de modo que podamos analizarlos posteriormente para detectar retrasos inesperados o excesivos.
Configuración de NGINX Plus
Empezamos configurando el servidor frontend NGINX Plus para incluir $request_id en un formato de registro personalizado, trace, que se utiliza para el archivo access_trace.log.
log_format trace '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for" $request_id';
upstream app_server {
server 10.0.0.1;
}
server {
listen 80;
add_header X-Request-ID $request_id; # Return to client
location / {
proxy_pass http://app_server;
proxy_set_header X-Request-ID $request_id; # Pass to app server
access_log /var/log/nginx/access_trace.log trace; # Log $request_id
}
}Configuración de la aplicación backend
Pasar el ID de solicitud a la aplicación está muy bien, pero no ayuda realmente a rastrearla a menos que esta haga algo con él. En este ejemplo, tenemos una aplicación de Python gestionada por uWSGI. Modifiquemos el punto de entrada de la aplicación para capturar el ID de solicitud como variable de registro.
from uwsgi import set_logvar
def main(environ, start_response):
set_logvar('requestid', environ['X_REQUEST_ID'])A continuación, podemos modificar la configuración de uWSGI para incluir el ID de solicitud en el archivo de registro estándar.
log-format = %(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size) "%(referer)" "%(uagent)" %(requestid)Con esta configuración, ahora generamos archivos de registro que pueden vincularse a una única solicitud en numerosos sistemas.
Entrada de registro de NGINX:
172.17.0.1 - - [02/Aug/2016:14:26:50 +0000] "GET / HTTP/1.1" 200 90 "-" "-" "-" 5f222ae5938482c32a822dbf15e19f0fEntrada de registro de la aplicación:
192.168.91.1 - - [02/Aug/2016:14:26:50 +0000] "GET / HTTP/1.0" 200 123 "-" "-" 5f222ae5938482c32a822dbf15e19f0fAl cotejar las transacciones con los campos de ID de solicitud, herramientas como Splunk y Kibana nos permiten identificar cuellos de botella de rendimiento en el servidor de su aplicación. Por ejemplo, podemos buscar solicitudes que hayan tardado más de dos segundos en completarse. Sin embargo, la resolución temporal predeterminada de un segundo de las marcas de tiempo convencionales es insuficiente para la mayoría de los análisis en situaciones reales.
Medición de tiempo de alta precisión
Para medir con precisión las solicitudes de extremo a extremo, necesitamos marcas de tiempo con una precisión de milisegundos. Al incluir la variable $msec en las entradas del registro, obtenemos una resolución de milisegundos en la marca de tiempo de cada entrada. Añadir marcas de tiempo en milisegundos al registro de nuestra aplicación nos permite buscar solicitudes que tardaron más de 200 milisegundos en completarse, en lugar de 2 segundos.
Pero aun así no obtenemos una visión completa, porque NGINX Plus registra la marca de tiempo $msec únicamente al finalizar el procesamiento de cada solicitud. Afortunadamente, existen otras variables de tiempo de NGINX Plus con precisión de milisegundos que nos permiten conocer mejor el propio procesamiento:
$request_time– Tiempo total de la solicitud, desde que NGINX Plus lee el primer byte del cliente hasta que envía el último byte del cuerpo de la respuesta$upstream_connect_time– Tiempo empleado en establecer una conexión con el servidor ascendente$upstream_header_time– Tiempo transcurrido entre el establecimiento de una conexión con el servidor ascendente y la recepción del primer byte de la cabecera de respuesta$upstream_response_time– Tiempo transcurrido entre el establecimiento de una conexión con el servidor ascendente y la recepción del último byte del cuerpo de la respuesta
Para obtener información detallada sobre estas variables de tiempo, consulte Uso de los registros de NGINX para supervisar el rendimiento de las aplicaciones.
Ampliemos nuestra directiva log_format para incluir todas estas variables de temporización de alta precisión en nuestro formato de registro trace.
log_format trace '$remote_addr - $remote_user [$time_local] "$request" $status ' '$body_bytes_sent "$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for" $request_id $msec $request_time '
'$upstream_connect_time $upstream_header_time $upstream_response_time';Con nuestra herramienta de análisis de registros preferida, podemos extraer los valores de las variables y realizar el siguiente cálculo para determinar cuánto tiempo tardó NGINX Plus en procesar la solicitud antes de conectarse al servidor de aplicaciones:
NGINX Plus processing time = $request_time - $upstream_connect_time - $upstream_response_timeTambién podemos buscar los valores más altos de $upstream_response_time para comprobar si están asociados a URI o servidores ascendentes concretos. Después, podemos cotejarlos con las entradas del registro de la aplicación que tengan el mismo ID de solicitud.
Conclusión
El uso de la nueva variable $request_id y de algunas o todas las variables con precisión de milisegundos puede proporcionar información muy valiosa sobre los cuellos de botella de rendimiento de su aplicación, lo que mejora la gestión del rendimiento sin tener que recurrir a agentes y complementos pesados.
Prueba por ti mismo el seguimiento de aplicaciones con NGINX Plus: inicia tu prueba gratuita de 30 días hoy mismo o contacta con nosotros para hablar sobre tus casos de uso.
Sobre el autor

Artículos relacionados del blog
Únete a F5 NGINX en AppWorld 2024
Descubre las numerosas razones para asistir al evento insignia de F5, que incluirá un emocionante anuncio sobre la cartera de productos NGINX.
Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source
La función de diccionario compartido permite configurar NGINX sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.
Exposición de APIs en Kubernetes
La unidad 2 de Microservices March 2022 se centra en cómo exponer tus API en Kubernetes. Aquí tienes enlaces a los recursos que necesitas: la retransmisión en directo del 14 de marzo, artículos de blog y otros recursos de preparación, y el laboratorio práctico «Protege las API de Kubernetes mediante la limitación de solicitudes».
NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto
Hoy, en NGINX Sprint 2.0, anunciamos cómo respaldaremos nuestra visión del futuro de las aplicaciones modernas con una mayor presencia en la comunidad de código abierto, incluida la participación en el proyecto comunitario Kubernetes, nuevos proyectos de software de código abierto y la arquitectura de referencia para aplicaciones modernas.
Presentamos NGINX Plus R22
NGINX Plus R22 incorpora nuevas funcionalidades, como la compatibilidad con OCSP para verificar la revocación de certificados en TLS mutuo, el uso de varios proveedores de identidad OIDC en una configuración, el seguimiento en tiempo real de la limitación de solicitudes y conexiones en el panel de NGINX Plus y mejoras en NGINX JavaScript.
Presentamos NGINX Plus R17
NGINX Plus R17 incorpora compatibilidad con la limitación de velocidad en dos fases y con TLS 1.3, la versión más reciente del protocolo Transport Layer Security. La configuración de OpenID Connect es más sencilla y NGINX ModSecurity WAF es el doble de rápido que antes. También se ha actualizado el módulo JavaScript de NGINX.