Ingeniería

Rastreo distribuido, OpenTracing y Elastic APM

El mundo de los microservicios

Las empresas están adoptando cada vez más las arquitecturas de microservicios. Están desarrollando y desplegando más microservicios todos los días. A menudo, estos servicios se desarrollan en diferentes lenguajes de programación, se despliegan en contenedores de tiempo de ejecución separados y son administrados por diferentes equipos y organizaciones. Las grandes empresas como Twitter pueden tener decenas de miles de microservicios, todos trabajando juntos para lograr sus objetivos comerciales. Tal como se analizó en este blog de Twitter, la visibilidad del estado y el rendimiento de la topología diversa de servicios es extremadamente importante para que puedan determinar rápidamente la causa raíz de los problemas, así como para aumentar la confiabilidad y la eficacia general de Twitter.

Aquí es donde el rastreo distribuido puede ayudar. El rastreo distribuido ayuda con dos desafíos fundamentales que enfrentan los microservicios:

  1. Rastreo de latencia
    La solicitud o transacción de un usuario puede viajar por varios servicios diferentes en distintos entornos de ejecución. Comprender la latencia de cada uno de estos servicios para una solicitud en particular es fundamental para comprender las características de rendimiento general del sistema en su conjunto y proporciona información valiosa para posibles mejoras.
  2. Análisis de la causa raíz
    El análisis de la causa raíz es aún más desafiante para las aplicaciones que se crean en grandes ecosistemas de microservicios. Algo puede salir mal con cualquiera de los servicios en cualquier momento. El rastreo distribuido es de importancia crucial cuando se depuran problemas en un sistema de este tipo.

A modo de reflexión, el rastreo es solo una pieza de los rompecabezas de los tres pilares de la observabilidad: logging, métricas y rastreo. Como veremos brevemente, el Elastic Stack es una plataforma unificada para los tres pilares de la observabilidad. Cuando los logs, las métricas y los datos de APM se almacenan en el mismo repositorio, se analizan y se correlacionan entre sí, obtienes la información más completa del contexto de tus aplicaciones y sistemas comerciales. En este blog, nos centraremos únicamente en el aspecto del rastreo.

Rastreo distribuido con Elastic APM

Elastic APM es un sistema de monitoreo de rendimiento de aplicaciones desarrollado en el Elastic Stack. Te permite monitorear servicios de software y aplicaciones en tiempo real, al recolectar información detallada sobre el rendimiento del tiempo de respuesta para solicitudes entrantes, consultas de bases de datos, llamadas a cachés, solicitudes HTTP externas, etc. Los agentes de Elastic APM ofrecen una instrumentación automática completa lista para usarse (por ejemplo, consultas de tiempo de la base de datos, etc.) para marcos de trabajo y tecnologías compatibles. También puedes usar la instrumentación personalizada para fines personalizados. Esto hace que sea mucho más fácil identificar y solucionar los problemas de rendimiento rápidamente.

Elastic APM admite el rastreo distribuido y es compatible con OpenTracing. Te permite analizar el rendimiento en toda tu arquitectura de microservicios en una sola vista. Elastic APM logra esto al rastrear todas las solicitudes, desde la solicitud web inicial hasta tu servicio de front-end, y hasta las consultas realizadas a tus servicios de back-end. Esto hace que encontrar posibles cuellos de botella en toda tu aplicación sea mucho más fácil y rápido. La visualización de la línea de tiempo en la UI de APM muestra una vista en cascada de todas las transacciones de servicios individuales que están conectados en un rastreo:

El Elastic Stack es también una gran plataforma para la agregación de logs y la analítica de métricas. Tener logs, métricas y rastreos de APM almacenados e indexados en Elasticsearch es muy poderoso. Ser capaz de correlacionar rápidamente las fuentes de datos como las métricas de infraestructura, logs y rastreos te permite depurar la causa raíz mucho más rápido. En la UI de APM, al observar un rastreo, puedes pasar rápidamente a las métricas y logs del host o del contenedor haciendo clic en el menú Actions (Acciones) si estas métricas y estos logs también se recopilan.

Sería maravilloso si todos usaran Elastic APM para instrumentar sus aplicaciones y servicios. Sin embargo, Elastic APM no es la única solución de rastreo distribuido disponible en la actualidad. Hay otros rastreadores populares de código abierto como Zipkin y Jaeger. Conceptos como la programación políglota y la persistencia políglota son muy conocidos y cuentan con gran aceptación en el mundo de los microservicios. Del mismo modo, el “rastreo políglota” será más común en la mayoría de los casos. Debido a la naturaleza independiente y disociada de los microservicios, las personas responsables de los diferentes servicios probablemente usarán diferentes sistemas de rastreo.

Desafíos para los desarrolladores

Con muchos sistemas de rastreo diferentes disponibles, los desarrolladores se enfrentan a verdaderos desafíos. Al fin de cuentas, los rastreadores viven dentro del código de la aplicación. Estos son algunos de los desafíos más comunes:

  1. ¿Qué sistema de rastreo usar?
  2. ¿Qué pasa si quiero cambiar mi rastreador? No quiero cambiar mi código fuente completo.
  3. ¿Qué hago con las bibliotecas compartidas que pueden estar usando diferentes rastreadores?
  4. ¿Qué pasa si mis servicios de terceros usan rastreadores diferentes?

No resulta sorprendente que necesitemos una estandarización para abordar estas inquietudes. Antes de analizar dónde nos encontramos con respecto a la estandarización, demos un paso atrás y analicemos el rastreo distribuido desde una perspectiva arquitectónica de manera holística y comprendamos lo que se necesita para lograr el rastreo distribuido “nirvana”.

Componentes de la arquitectura del rastreo distribuido

Los sistemas de software modernos pueden dividirse en algunos componentes de alto nivel, diseñados y desarrollados habitualmente por diferentes organizaciones y ejecutados en diferentes entornos de ejecución.

  • Tu propio código de aplicación y servicios
  • Bibliotecas y servicios compartidos
  • Servicios externos

Para monitorear un sistema de este tipo de manera holística e integrada con el rastreo distribuido, necesitamos cuatro componentes de arquitectura:

  1. Una API de rastreo distribuido estandarizada. Una API estandarizada de rastreo neutral para los proveedores permite a los desarrolladores instrumentar su código de una manera estandarizada, sin importar qué rastreador elijan usar más adelante durante el tiempo de ejecución. Este es el primer paso para cualquier cosa.
  2. Definición de contexto y propagación de rastreo estandarizados. Para que un rastreo pase de un tiempo de ejecución a otro, ambas partes deben comprender el contexto de rastreo y debe haber una manera estándar de propagar ese contexto. Como mínimo, el contexto lleva una identificación de rastreo.
  3. Definición de datos de rastreo estandarizados. Para que un rastreador pueda comprender y consumir los datos de rastreo de otro rastreador, debe haber un formato estandarizado y extensible para ellos.
  4. Rastreadores interoperables. Finalmente, para lograr una compatibilidad del 100 % con el tiempo de ejecución, los diferentes rastreadores deben proporcionar mecanismos para exportar e importar datos de rastreo de otros rastreadores de forma abierta. Idealmente, una biblioteca o un servicio compartidos instrumentados por un rastreador como Jaeger debería poder enviar sus datos de rastreo directamente a Elastic APM u otro rastreador mediante el agente de Jaeger a través de un cambio de configuración.

Aquí es donde entra en juego OpenTracing.

La especificación de OpenTracing

La especificación de OpenTracing define una API abierta y neutral para proveedores destinada al rastreo distribuido. Permite a los usuarios evitar el bloqueo de proveedores al permitirles cambiar el implementador de OpenTracing en cualquier momento. También permite a los desarrolladores de marcos de trabajo y bibliotecas compartidas proporcionar una funcionalidad de rastreo lista para usarse, de forma estándar para permitir una mejor comprensión de los marcos de trabajo y las bibliotecas. Las compañías de escala web como Uber y Yelp están usando OpenTracing para obtener una mayor visibilidad de sus aplicaciones dinámicas y altamente distribuidas.

El modelo de datos de OpenTracing

Los conceptos básicos de OpenTracing y el modelo de datos fundamental provienen del documento sobre Dapper de Google. Los conceptos clave incluyen los términos rastreo e intervalo.

  1. Un rastreo representa una transacción a medida que se mueve a través de un sistema distribuido. Se puede considerar como un grafo acíclico dirigido de intervalos.
  2. Un intervalo representa una unidad lógica de trabajo que tiene un nombre, una hora de inicio y una duración. Los intervalos pueden estar anidados y ordenados para modelar relaciones. Los intervalos aceptan etiquetas de clave:valor, así como logs refinados, con marca de tiempo y estructurados adjuntos a la instancia de intervalo en particular.
  3. El contexto de rastreo es la información de rastreo que acompaña a la transacción distribuida, incluso cuando pasa de un servicio a otro a través de la red o por un bus de mensaje. El contexto contiene el identificador de rastreo, el identificador de intervalo y cualquier otro dato que el sistema de rastreo necesite para propagarse al servicio que sigue en la cadena.

¿Cómo encaja todo esto?

Idealmente, con la estandarización, la información de rastreo de un código de aplicación personalizado, las bibliotecas compartidas y los servicios compartidos desarrollados y administrados por diferentes organizaciones son intercambiables y compatibles con el tiempo de ejecución, sin importar qué rastreador elija cada uno de estos componentes.

Sin embargo, OpenTracing solo aborda el primero de los cuatro componentes de arquitectura que analizamos anteriormente. Entonces, ¿dónde nos encontramos en la actualidad con respecto a los demás componentes y qué nos depara el futuro?

¿Dónde nos encontramos en la actualidad?

Como ya analizamos, OpenTracing define un conjunto estándar de API de rastreo para que las implementen diferentes rastreadores, lo que es un gran comienzo y es muy alentador. Sin embargo, aún necesitamos la estandarización del contexto de rastreo y la estandarización de los datos de rastreo para que sean compatibles e intercambiables entre sí.

  1. La API de OpenTracing proporciona un conjunto estándar de API. Esta es prácticamente la única estandarización que tenemos al día de hoy. La especificación también tiene una limitación. Por ejemplo, no cubre todos los lenguajes de programación. No obstante, es un gran esfuerzo y está ganando muchos adeptos.
  2. Aún no hay una definición de contexto de rastreo estandarizado. El W3C Distributed Tracing Work Group está en el proceso de estandarizar la definición del contexto de rastreo: la especificación del contexto de rastreo de W3C. La especificación define un enfoque unificado para el contexto y una correlación de eventos dentro de los sistemas distribuidos, y permitirá el rastreo de transacciones de extremo a extremo dentro de las aplicaciones distribuidas en diferentes herramientas de monitoreo. Elastic APM apoya el esfuerzo del grupo de trabajo para contexto de rastreo de W3C a fin de estandarizar el formato de la cabecera HTTP para el rastreo distribuido. Nuestras implementaciones de agentes siguen detenidamente la especificación preliminar del contexto de rastreo y planeamos apoyar en su totalidad la especificación final.

    Como ejemplo de la incompatibilidad del contexto de rastreo en la actualidad, a continuación se proporciona un ejemplo de cabecera HTTP usado por Elastic APM y Jaeger para la identificación de rastreo. Como puedes ver, tanto el nombre como el codificado de la identificación son diferentes. Cuando se usan diferentes cabeceras de rastreo, los rastreos se romperán cuando crucen los límites de las herramientas de rastreo respectivas.

    Jaeger:
    uber-trace-id: 118c6c15301b9b3b3:56e66177e6e55a91:18c6c15301b9b3b3:1

    Elastic APM:
    elastic-apm-traceparent: 00-f109f092a7d869fb4615784bacefcfd7-5bf936f4fcde3af0-01

    También existen otros desafíos, además de la definición en sí. Por ejemplo, no todas las cabeceras HTTP se reenvían automáticamente por parte de la infraestructura de servicio y los routers, etc. Cada vez que se quiten las cabeceras, el rastreo se romperá.
  3. Aún no hay una definición de datos de rastreo estandarizados. Según lo declarado por el W3C Distributed Tracing Work Group, la segunda pieza del rompecabezas para la interoperabilidad de rastreo es “un formato estandarizado y extensible para compartir datos de rastreo (rastreos completos o fragmentos de rastreos) a través de herramientas para una mayor interpretación”. Como puedes imaginar, con tantos operadores de código abierto y comerciales involucrados, acordar un formato estándar no es algo fácil. Esperemos que lleguemos a eso pronto.
  4. Los rastreadores no son compatibles con el tiempo de ejecución. Debido a todo lo que analizamos anteriormente, además de la motivación combinada de hacer que su sistema sea abierto y compatible con el resto del mundo, los rastreadores simplemente no son compatibles entre sí durante el tiempo de ejecución en la actualidad. Puedo decir con confianza que probablemente esto se mantenga así en el futuro previsible.

Cómo funciona Elastic APM con otros rastreadores en la actualidad

A pesar de que no estamos ni cerca del 100 % de compatibilidad entre los rastreadores aún hoy, no tenemos por qué desalentarnos. El Elastic Stack aún puede trabajar con otros rastreadores de varias maneras diferentes.

  1. Elasticsearch como el almacén de datos de backend escalable para otros rastreadores.

    No resulta sorprendente que Elasticsearch se haya usado como almacén de datos de backend para otros rastreadores como Zipkin y Jaeger, debido a su escalabilidad masiva e innumerables capacidades de analítica. Enviar los datos de rastreo de Zipkin o Jaeger a Elasticsearch es una configuración simple para ambos. Una vez que los datos de rastreo están dentro de Elasticsearch, puedes usar la potente capacidad analítica y de visualización de Kibana para analizar tu información de rastreo y crear visualizaciones llamativas que brinden un conocimiento profundo del rendimiento de tu aplicación.
  2. Puente OpenTracing de Elastic

    El puente OpenTracing de Elastic APM te permite crear transacciones e intervalos de Elastic APM, mediante el uso de la API de OpenTracing. En otras palabras, traduce las llamadas a la API de OpenTracing a Elastic APM y, por lo tanto, permite reutilizar la instrumentación existente. Por ejemplo, una instrumentación existente realizada por Jaeger puede reemplazarse simplemente con Elastic APM al cambiar un par de líneas de código.

    Instrumentación original de Jaeger:

    import io.opentracing.Scope;
    import io.opentracing.Tracer;
    import io.jaegertracing.Configuration;
    import io.jaegertracing.internal.JaegerTracer;
    ...
    private void sayHello(String helloTo) {
        Configuration config = ...
        Tracer tracer = config.getTracer();
        try (Scope scope = tracer.buildSpan("say-hello").startActive(true)) {
            scope.span().setTag("hello-to", helloTo);
        }
        ...
    }
        
    Reemplaza Jaeger con el puente OpenTracing de Elastic:

    import io.opentracing.Scope;
    import io.opentracing.Tracer;
    import co.elastic.apm.opentracing.ElasticApmTracer;
    ...
    private void sayHello(String helloTo) {
        Tracer tracer = new ElasticApmTracer();
        try (Scope scope = tracer.buildSpan("say-hello").startActive(true)) {
            scope.span().setTag("hello-to", helloTo);
        }
        ...
    }
        


    Con este simple cambio, los datos de rastreo fluirán sin problemas en Elastic APM, sin que tengas que modificar otro código de rastreo. ¡Ese es el poder de OpenTracing!

Monitoreo de usuario real de Elastic APM

Si bien nos centramos principalmente en los servicios backend cuando se analiza el rastreo y la propagación del contexto, etc., hay un gran valor para iniciar el rastreo en el lado del cliente en el navegador. Al hacerlo, obtienes información de rastreo en el momento en que un usuario hace clic en algo en el navegador. Esa información de rastreo representa la experiencia de usuario real” de tus aplicaciones desde el aspecto del rendimiento. Lamentablemente, de nuevo, no existe una forma estandarizada de enviar esa información hoy. El grupo W3C tiene la intención de extender el contexto de rastreo hasta el navegador en el futuro.

El monitoreo de usuario real de Elastic APM (RUM) proporciona exactamente esa funcionalidad en la actualidad. El agente de RUM JS supervisa la experiencia de usuario real dentro de tu aplicación del lado del cliente. Podrás medir métricas como "Tiempo hasta el primer byte", domInteractive y domComplete, lo que te ayuda a descubrir problemas de rendimiento en tu aplicación del lado del cliente, así como problemas relacionados con la latencia de tu aplicación del lado del servidor. Nuestro agente de RUM JS es independiente del marco de trabajo, lo que significa que se puede usar con cualquier aplicación de frontend basada en JavaScript.

<p?</p?

Resumen

Con suerte, este blog te ayudó a comprender mejor el panorama de rastreo distribuido y aclaró algunas de las confusiones acerca de dónde nos encontramos hoy con OpenTracing. Concluyamos por hoy con un breve resumen:

  1. El rastreo distribuido proporciona una perspectiva de rendimiento invaluable para microservicios.
  2. OpenTracing es el primer paso de la industria hacia la estandarización para el rastreo distribuido. Todavía tenemos un largo camino por recorrer para una compatibilidad total.
  3. Elastic APM es compatible con OpenTracing.
  4. El puente OpenTracing de Elastic permite volver a usar la instrumentación.
  5. El Elastic Stack es un gran almacenamiento a largo plazo escalable para otros rastreadores como Zipkin y Jaeger, incluso sin compatibilidad total con el tiempo de ejecución en la actualidad.
  6. Elastic proporciona una analítica profunda para rastrear datos de Elastic u otros datos. El envío de datos de rastreo de Zipkin o Jaeger a Elasticsearch implica una configuración simple.
  7. El monitoreo de usuario real de Elastic APM (RUM) monitorea la experiencia de usuario real dentro de tu aplicación del lado del cliente.
  8. En conclusión, Elastic es una plataforma de analítica masivamente escalable, con múltiples funciones y unificada para los tres pilares de la observabilidad: logging, métricas y rastreo.

Como siempre, accede al foro de Elastic APM si deseas abrir un debate o tienes alguna pregunta. ¡Feliz rastreo!