A pesar de todos sus beneficios, una arquitectura de microservicios también introduce nuevas complejidades. Uno de ellos es el desafío de rastrear las solicitudes a medida que se procesan, con los datos fluyendo entre todos los microservicios que componen la aplicación. Para este propósito se ha inventado una nueva metodología llamada rastreo distribuido (de solicitud) , y OpenTracing es una especificación y un conjunto estándar de API destinadas a guiar el diseño y la implementación de herramientas de rastreo distribuido.
En NGINX Plus Release 18 (R18) , agregamos el módulo NGINX OpenTracing a nuestro repositorio de módulos dinámicos (ha estado disponible como un módulo de terceros en GitHub desde hace un par de años). Una gran ventaja del módulo NGINX OpenTracing es que al instrumentar NGINX y NGINX Plus para el seguimiento distribuido, se obtienen datos de seguimiento para cada aplicación proxy, sin tener que instrumentar las aplicaciones individualmente.
En este blog mostramos cómo habilitar el seguimiento distribuido de solicitudes para NGINX o NGINX Plus (para abreviar, de ahora en adelante nos referiremos a NGINX Plus ). Proporcionamos instrucciones para dos servicios de rastreo distribuido ( trazadores , en la terminología de OpenTracing), Jaeger y Zipkin . (Para obtener una lista de otros trazadores, consulte la documentación de OpenTracing ). Para ilustrar el tipo de información proporcionada por los rastreadores, comparamos el procesamiento de solicitudes antes y después de habilitar el almacenamiento en caché de NGINX Plus.
Un trazador tiene dos componentes básicos:
El primer paso es instalar y configurar el servidor para el rastreador de su elección. Estamos proporcionando instrucciones para Jaeger y Zipkin; adáptelas según sea necesario para otros trazadores.
Recomendamos el siguiente método para instalar el servidor Jaeger. También puedes descargar imágenes de Docker en la URL especificada en el Paso 1.
Vaya a la página de descarga de Jaeger y descargue el binario de Linux (al momento de escribir este artículo, jaeger-1.12.0-linux-amd64.tar ).
Mueva el binario a /usr/bin/jaeger (creando el directorio primero si es necesario) y ejecútelo.
$ mkdir /usr/bin/jaeger$ mv jaeger-1.12.0-linux-amd64.tar /usr/bin/jaeger
$ cd /usr/bin/jaeger
$ tar xvzf jaeger-1.12.0-linux-amd64.tar.gz
$ sudo rm -rf jaeger-1.12.0-linux-amd64.tar.gz
$ cd jaeger-1.12.0-linux-amd64
$ ./jaeger-all-in-one
Verifique que pueda acceder a la interfaz de usuario de Jaeger en su navegador, en http:// Jaeger-server-IP-address :16686/ (16686 es el puerto predeterminado para el servidor Jaeger).
Descargue y ejecute una imagen Docker de Zipkin (estamos usando el puerto 9411, el predeterminado).
$ docker run -d -p 9411:9411 openzipkin/zipkin
Verifique que pueda acceder a la interfaz de usuario de Zipkin en su navegador, en http:// Zipkin-server-IP-address :9411/ .
Ejecute estos comandos en el host NGINX Plus para instalar el complemento para Jaeger o Zipkin.
Instalar el complemento Jaeger. El siguiente comando wget
es para sistemas Linux x86‑64:
$ cd /usr/local/lib
$ wget https://github.com/jaegertracing/jaeger-client-cpp/releases/download/v0.4.2/libjaegertracing_plugin.linux_amd64.so -O /usr/local/lib/libjaegertracing_plugin.so
Las instrucciones para crear el complemento desde la fuente están disponibles en GitHub .
Cree un archivo de configuración con formato JSON para el complemento, llamado /etc/jaeger/jaeger-config.json , con el siguiente contenido. Estamos utilizando el puerto predeterminado para el servidor Jaeger, 6831:
{ "service_name": "nginx",
"sampler": {
"type": "const",
"param": 1
},
"reporter": {
"localAgentHostPort": "Jaeger-server-IP-address:6831"
}
}
Para obtener detalles sobre el objeto sampler
, consulte la documentación de Jaeger .
Instalar el complemento Zipkin. El siguiente comando wget
es para sistemas Linux x86‑64:
$ cd /usr/local/lib$ wget -O - https://github.com/rnburn/zipkin-cpp-opentracing/releases/download/v0.5.2/linux-amd64-libzipkin_opentracing_plugin.so.gz | gunzip -c > /usr/local/lib/libzipkin_opentracing_plugin.so
Cree un archivo de configuración con formato JSON para el complemento, llamado /etc/zipkin/zipkin-config.json , con el siguiente contenido. Estamos utilizando el puerto predeterminado para el servidor Zipkin, 9411:
{ "service_name": "nginx",
"collector_host": "Zipkin-server-IP-address",
"collector_port": 9411
}
Para obtener detalles sobre los objetos de configuración, consulte el esquema JSON en GitHub .
Ejecute estas instrucciones en el host NGINX Plus.
Instale el módulo NGINX OpenTracing de acuerdo con las instrucciones de la Guía de administración de NGINX Plus .
Agregue la siguiente directiva load_module
en el contexto principal (de nivel superior) del archivo de configuración principal de NGINX Plus ( /etc/nginx/nginx.conf ):
load_module modules/ngx_http_opentracing_module.so;
Agregue las siguientes directivas a la configuración de NGINX Plus.
Si utiliza el esquema de configuración convencional , coloque las directivas en un nuevo archivo llamado /etc/nginx/conf.d/opentracing.conf . Verifique también que la siguiente directiva de inclusión
aparezca en el contexto http
en /etc/nginx/nginx.conf :
http {
include /etc/nginx/conf.d/*.conf;
}
opentracing_load_tracer
habilita el complemento tracer. Descomente la directiva de Jaeger o Zipkin según corresponda.opentracing_tag
hacen que las variables NGINX Plus estén disponibles como etiquetas OpenTracing que aparecen en la interfaz de usuario del trazador.log_format
y access_log
. Si desea reemplazar el registro de acceso NGINX predeterminado y el formato de registro con este, descomente las directivas y luego cambie las tres instancias de “ opentracing
” a “ main
”. Otra opción es registrar la actividad de OpenTracing solo para el tráfico en el puerto 9001: descomente las directivas log_format
y access_log
y muévalas al bloque del servidor
.de servidor
configura OpenTracing para la aplicación Ruby de muestra que se describe en la siguiente sección .# Load a vendor tracer#opentracing_load_tracer /usr/local/libjaegertracing_plugin.so
# /etc/jaeger/jaeger-config.json;
#opentracing_load_tracer /usr/local/lib/libzipkin_opentracing_plugin.so
# /etc/zipkin/zipkin-config.json;
# Enable tracing for all requests
opentracing on;
# Set additional tags that capture the value of NGINX Plus variables
opentracing_tag bytes_sent $bytes_sent;
opentracing_tag http_user_agent $http_user_agent;
opentracing_tag request_time $request_time;
opentracing_tag upstream_addr $upstream_addr;
opentracing_tag upstream_bytes_received $upstream_bytes_received;
opentracing_tag upstream_cache_status $upstream_cache_status;
opentracing_tag upstream_connect_time $upstream_connect_time;
opentracing_tag upstream_header_time $upstream_header_time;
opentracing_tag upstream_queue_time $upstream_queue_time;
opentracing_tag upstream_response_time $upstream_response_time;
#uncomment for debugging
# log_format opentracing '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for" '
# '"$host" sn="$server_name" '
# 'rt=$request_time '
# 'ua="$upstream_addr" us="$upstream_status" '
# 'ut="$upstream_response_time" ul="$upstream_response_length" '
# 'cs=$upstream_cache_status';
#access_log /var/log/nginx/opentracing.log opentracing;
server {
listen 9001;
location / {
# The operation name used for OpenTracing Spans defaults to the name of the
# 'location' block, but uncomment this directive to customize it.
#opentracing_operation_name $uri;
# Propagate the active Span context upstream, so that the trace can be
# continued by the backend.
opentracing_propagate_context;
# Make sure that your Ruby app is listening on port 4567
proxy_pass http://127.0.0.1:4567;
}
}
Validar y recargar la configuración de NGINX Plus:
$ nginx -t$ nginx -s reload
Con el trazador y la configuración de NGINX Plus en su lugar, creamos una aplicación Ruby de muestra que muestra cómo se ven los datos de OpenTracing. La aplicación nos permite medir en qué medida el almacenamiento en caché de NGINX Plus mejora el tiempo de respuesta. Cuando la aplicación recibe una solicitud como la siguiente solicitud HTTP GET
para / , espera una cantidad de tiempo aleatoria (entre 2 y 5 segundos) antes de responder.
$ curl http://NGINX-Plus-IP-address:9001/
Instala y configura tanto Ruby como Sinatra (una biblioteca open source software para aplicaciones web y un lenguaje específico de dominio escritos en Ruby, que aportan una alternativa a otros frameworks de aplicaciones web en Ruby).
Crea un archivo llamado app.rb con el siguiente contenido:
#!/usr/bin/ruby
require 'sinatra'
get '/*' do
out = "<h1>Ruby simple app</h1>" + "\n"
#Sleep a random time between 2s and 5s
sleeping_time = rand(4)+2
sleep(sleeping_time)
puts "slept for: #{sleeping_time}s."
out += '<p>some output text</p>' + "\n"
return out
end
Haga que app.rb sea ejecutable y ejecútelo:
$ chmod +x app.rb$ ./app.rb
Usamos Jaeger y Zipkin para mostrar cuánto tiempo le toma a NGINX Plus responder a una solicitud cuando el almacenamiento en caché no está habilitado. Para cada trazador, enviamos cinco solicitudes.
Aquí se muestran las cinco solicitudes que se muestran en la interfaz de usuario de Jaeger (la más reciente primero):
Aquí está la misma información en la consola de la aplicación Ruby:
- -> /slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:50:46 +0000] "GET / HTTP/1.1" 200 49 3.0028
127.0.0.1 - - [07/Jun/2019: 10:50:43 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 2s.
127.0.0.1 - - [07/Jun/2019: 10:50:56 +0000] "GET / HTTP/1.1" 200 49 2.0018
127.0.0.1 - - [07/Jun/2019: 10:50:54 UTC] "GET / HTTP/1.0"1 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:53:16 +0000] "GET / HTTP/1.1" 200 49 3.0029
127.0.0.1 - - [07/Jun/2019: 10:53:13 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 4s.
127.0.0.1 - - [07/Jun/2019: 10:54:03 +0000] "GET / HTTP/1.1" 200 49 4.0030
127.0.0.1 - - [07/Jun/2019: 10:53:59 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:54:11 +0000] "GET / HTTP/1.1" 200 49 3.0012
127.0.0.1 - - [07/Jun/2019: 10:54:08 UTC] "GET / HTTP/1.0" 200 49
En la interfaz de usuario de Jaeger, hacemos clic en la primera solicitud (la más reciente) para ver detalles sobre ella, incluidos los valores de las variables NGINX Plus que agregamos como etiquetas:
Aquí hay otras cinco solicitudes en la interfaz de usuario de Zipkin:
La misma información en la consola de la aplicación Ruby:
- -> /slept for: 2s.
127.0.0.1 - - [07/Jun/2019: 10:31:18 +0000] "GET / HTTP/1.1" 200 49 2.0021
127.0.0.1 - - [07/Jun/2019: 10:31:16 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:31:50 +0000] "GET / HTTP/1.1" 200 49 3.0029
127.0.0.1 - - [07/Jun/2019: 10:31:47 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:32:08 +0000] "GET / HTTP/1.1" 200 49 3.0026
127.0.0.1 - - [07/Jun/2019: 10:32:05 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:32:32 +0000] "GET / HTTP/1.1" 200 49 3.0015
127.0.0.1 - - [07/Jun/2019: 10:32:29 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 5s.
127.0.0.1 - - [07/Jun/2019: 10:32:52 +0000] "GET / HTTP/1.1" 200 49 5.0030
127.0.0.1 - - [07/Jun/2019: 10:32:47 UTC] "GET / HTTP/1.0" 200 49
En la interfaz de usuario de Zipkin, hacemos clic en la primera solicitud para ver detalles sobre ella, incluidos los valores de las variables NGINX Plus que agregamos como etiquetas:
Habilitamos el almacenamiento en caché agregando directivas en el archivo opentracing.conf que creamos en Configuración de NGINX Plus .
En el contexto http
, agregue esta directiva proxy_cache_path
:
proxy_cache_path /data/nginx/cache keys_zone=one:10m;
En el bloque del servidor
, agregue las siguientes directivas proxy_cache
y proxy_cache_valid
:
proxy_cache one;
proxy_cache_valid any 1m;
Validar y recargar la configuración:
$ nginx -t$ nginx -s reload
Aquí está la interfaz de usuario de Jaeger después de dos solicitudes.
La primera respuesta (etiquetada 13f69db ) tardó 4 segundos. NGINX Plus almacenó en caché la respuesta y, cuando la solicitud se repitió unos 15 segundos después, la respuesta tardó menos de 2 milisegundos (ms) porque provenía del caché de NGINX Plus.
Analizar las dos solicitudes en detalle explica la diferencia en el tiempo de respuesta. Para la primera solicitud, upstream_cache_status
es MISS
, lo que significa que los datos solicitados no estaban en la memoria caché. La aplicación Ruby agregó un retraso de 4 segundos.
Para la segunda solicitud, upstream_cache_status
es HIT
. Como los datos provienen de la memoria caché, la aplicación Ruby no puede agregar un retraso y el tiempo de respuesta es inferior a 2 ms. Los valores upstream_*
vacíos también indican que el servidor ascendente no estuvo involucrado en esta respuesta.
La visualización en la interfaz de usuario de Zipkin para dos solicitudes con almacenamiento en caché habilitado muestra una imagen similar:
Y nuevamente, al observar las dos solicitudes en detalle, se explica la diferencia en el tiempo de respuesta. La respuesta no se almacena en caché para la primera solicitud ( upstream_cache_status
es MISS
) y la aplicación Ruby (casualmente) agrega el mismo retraso de 4 segundos que en el ejemplo de Jaeger.
La respuesta se ha almacenado en caché antes de que hagamos la segunda solicitud, por lo que upstream_cache_status
es HIT
.
El módulo NGINX OpenTracing permite el seguimiento de solicitudes y respuestas de NGINX Plus y proporciona acceso a variables de NGINX Plus mediante etiquetas OpenTracing. También se pueden utilizar diferentes trazadores con este módulo.
Para obtener más detalles sobre el módulo NGINX OpenTracing, visita el repositorio del módulo NGINX OpenTracing en GitHub.
Para probar OpenTracing 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.