BLOG | NGINX

Seguimiento de aplicación con NGINX y NGINX Plus

Miniatura de Liam Crilly
Liam Crilly
Publicado el 27 de septiembre de 2016
Foto: WordPress.org

Uso de variables para la gestión del rendimiento de las aplicación

Las variables son un aspecto importante y a veces pasado por alto de la configuración de NGINX. Con aproximadamente 150 variables disponibles, hay variables para mejorar cada parte de su configuración. En esta publicación de blog, analizamos cómo usar las variables NGINX para el seguimiento de aplicación y la gestión del rendimiento de aplicación (APM), con el foco puesto en descubrir cuellos de botella en el rendimiento de su aplicación. Esta publicación se aplica tanto a NGINX Open Source como a NGINX Plus. Para abreviar, nos referiremos a NGINX Plus en todo momento, excepto cuando haya una diferencia entre las dos versiones.

El entorno de entrega de aplicación

En nuestro entorno de entrega de aplicación de muestra, NGINX Plus funciona como un proxy inverso para nuestra aplicación. La aplicación en sí se compone de una interfaz web detrás de la cual se encuentran una serie de microservicios.

En un escenario de implementación común, NGINX o NGINX Plus envía solicitudes de clientes a una aplicación o un servidor de aplicación que consta de una interfaz web y microservicios de soporte.
Entorno de entrega de aplicación de muestra

Seguimiento de solicitudes de extremo a extremo

NGINX Plus R10 (y NGINX 1.11.0) presenta la variable $request_id , que es una cadena generada aleatoriamente de 32 caracteres hexadecimales que se asigna automáticamente a cada solicitud HTTP a medida que llega (por ejemplo, 444535f9378a3dfa1b8604bc9e05a303 ). Este mecanismo engañosamente simple desbloquea una herramienta poderosa para el rastreo y la resolución de problemas. Al configurar NGINX Plus y todos los servicios backend para pasar el valor $request_id , puede rastrear cada solicitud de extremo a extremo. Esta configuración de muestra es para nuestro servidor frontend NGINX Plus.

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 rastreo de solicitudes, primero definimos la ubicación de red del servidor de aplicación en el bloque ascendente . Para simplificar, aquí solo mostramos un único servidor de aplicación , pero normalmente usaríamos varios para fines de alta disponibilidad y equilibrio de carga.

El bloque del servidor de aplicación define cómo NGINX Plus maneja las solicitudes HTTP entrantes. La directiva listen le dice a NGINX Plus que escuche en el puerto 80, el predeterminado para el tráfico HTTP, pero una configuración de producción normalmente usa SSL/TLS para proteger los datos en tránsito .

La directiva add_header envía el valor $request_id al cliente como un encabezado personalizado en la respuesta. Esto es útil para realizar pruebas y también para aplicaciones cliente que generan sus propios registros, como aplicaciones móviles, de modo que un error del lado del cliente pueda coincidir con precisión con los registros del servidor.

Finalmente, el bloque de ubicación se aplica a todo el espacio de la aplicación ( / ) y la directiva proxy_pass simplemente envía todas las solicitudes al servidor de aplicación . La directiva proxy_set_header modifica la solicitud enviada por proxy agregando un encabezado HTTP que se pasa a la aplicación. En este caso creamos un nuevo encabezado llamado X-Request-ID y le asignamos el valor de la variable $request_id . Entonces, 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 aplicación es identificar cuellos de botella de rendimiento en el ciclo de vida del procesamiento de solicitudes como parte de la gestión del rendimiento de las aplicación . Lo hacemos registrando eventos importantes durante el procesamiento para poder analizarlos más tarde en busca de retrasos inesperados o irrazonables.

Configuración de NGINX Plus

Comenzamos 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 su aplicación está muy bien, pero en realidad no ayuda con el rastreo de la aplicación a menos que la aplicación haga algo con él. En este ejemplo, tenemos una aplicación Python administrada por uWSGI . Modifiquemos el punto de entrada de la aplicación para obtener 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'])

Luego 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 implementada, ahora estamos produciendo archivos de registro que pueden vincularse a una sola 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 "-" "-" "-" 5f222ae5938482c32a822dbf15e19f0f

Entrada de registro de la aplicación:

192.168.91.1 - - [02/Aug/2016:14:26:50 +0000] "GET / HTTP/1.0" 200 123 "-" "-" 5f222ae5938482c32a822dbf15e19f0f

Al hacer coincidir las transacciones con los campos de ID de solicitud, herramientas como Splunk y Kibana nos permiten identificar cuellos de botella de rendimiento en su servidor de aplicación . Por ejemplo, podemos buscar solicitudes que tardaron más de dos segundos en completarse. Sin embargo, la resolución de tiempo predeterminada de un segundo en las marcas de tiempo regulares es insuficiente para la mayoría de los análisis del mundo real.

Sincronización 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. Agregar marcas de tiempo de milisegundos a nuestro registro de aplicación nos permite buscar solicitudes que tardaron más de 200 milisegundos en completarse en lugar de 2 segundos.

Pero incluso entonces no obtenemos la imagen completa, porque NGINX Plus escribe la marca de tiempo $msec solo al final del procesamiento de cada solicitud. Afortunadamente, hay otras variables de tiempo NGINX Plus con precisión de milisegundos que nos brindan más información sobre el procesamiento en sí:

  • $request_time – Tiempo total de solicitud, que comienza cuando NGINX Plus lee el primer byte del cliente y finaliza cuando NGINX Plus 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 entre el establecimiento de una conexión con el servidor ascendente y la recepción del primer byte del encabezado de respuesta
  • $upstream_response_time – Tiempo 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 del registro de NGINX para la supervisión del rendimiento de las aplicación .

Ampliemos nuestra directiva log_format para incluir todas estas variables de tiempo de alta precisión en nuestro formato de registro de seguimiento .

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

Usando nuestra herramienta de análisis de registros preferida, podemos extraer valores de variables y realizar el siguiente cálculo para ver cuánto tiempo tardó NGINX Plus en procesar la solicitud antes de conectarse al servidor de aplicación :

NGINX Plus processing time = $request_time - $upstream_connect_time - $upstream_response_time

También podemos buscar los valores más altos de $upstream_response_time para ver si están asociados con URI o servidores ascendentes particulares. Y luego estos se pueden comprobar más a fondo con las entradas del registro de la aplicación que tienen el mismo ID de solicitud.

CONCLUSIÓN

El uso de la nueva variable $request_id y algunas o todas las variables con precisión de milisegundos puede brindar una gran perspectiva de los cuellos de botella en el rendimiento de su aplicación, mejorando la gestión del rendimiento de la aplicación sin tener que recurrir a agentes y complementos pesados.

Pruebe usted mismo el rastreo de aplicación con NGINX Plus: comience hoy su prueba gratuita de 30 días o contáctenos para analizar sus casos de uso .


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