Desconstruyendo el Rastreo Distribuido

Rate this content
Bookmark
Slides

El rastreo distribuido es una técnica poderosa que te permite seguir el flujo y el tiempo de las solicitudes a medida que navegan a través de un sistema. Al vincular operaciones y solicitudes entre múltiples servicios, el rastreo distribuido proporciona valiosos conocimientos sobre el rendimiento de la aplicación y ayuda a identificar cuellos de botella. En esta charla, Lazar explicará el concepto de Rastreo Distribuido guiándote a través de cómo las herramientas de monitoreo construyen soluciones de rastreo.

Lazar Nikolov
Lazar Nikolov
8 min
12 Dec, 2023

Video Summary and Transcription

El rastreo distribuido es una técnica poderosa para rastrear solicitudes y operaciones en un sistema, especialmente en aplicaciones de pila completa y microservicios. La reinvención del rastreo distribuido introduce el concepto de un rastro y abarca para capturar datos de depuración. Las mejoras incluyen etiquetas y un campo de estado para un mejor análisis, y la distribución de rastros utilizando un contexto de rastro para un rastreo continuo.

Available in English

1. Introducción a la Trazabilidad Distribuida

Short description:

La trazabilidad distribuida es una técnica poderosa que ayuda a rastrear el flujo y el tiempo de las solicitudes y operaciones en un sistema. Es especialmente útil para aplicaciones de pila completa y microservicios, permitiendo una mejor comprensión del rendimiento del sistema e identificación de cuellos de botella. La técnica ha estado presente desde principios de los años 2000 pero ganó popularidad en la década de 2010. A medida que las bibliotecas y los marcos evolucionaron, también lo hicieron las herramientas de depuración, desde los registros en Apache Server hasta el manejo de múltiples solicitudes en un solo proceso con hilos separados. Con la concurrencia avanzada, marcos como Node.js permiten que las solicitudes comiencen y terminen en diferentes hilos.

♪ ♪ Reconstruyendo la trazabilidad distribuida. Hola a todos. Mi nombre es Laza Nikolov, y soy un defensor del desarrollo en Sentry. Hoy en mi charla, vamos a hablar sobre la trazabilidad distribuida. Primero explicaré qué es. Luego vamos a entrar un poco en la historia de las herramientas de depuración para descubrir por qué existía la trazabilidad distribuida en primer lugar. Y luego, para entenderlo mejor, vamos a reconstruir la trazabilidad distribuida desde cero o al menos solo el concepto de ella.

Muy bien, entonces, sumerjámonos. La trazabilidad distribuida es una técnica poderosa que te permite rastrear el flujo y el tiempo de las solicitudes y operaciones a medida que fluyen a través de tu sistema. Esto es especialmente útil para la pila completa y para las aplicaciones de microservicios. La trazabilidad distribuida te ayuda a entender el rendimiento del sistema e identificar cualquier cuello de botella. Es especialmente útil para depurar errores complejos y extraños como los errores de condición de carrera que requieren mucho más que solo un bloqueo de consola y un rastreo de pila. No es nuevo por ningún medio. Hay documentos técnicos que mencionan la trazabilidad desde principios de los años 2000, pero se popularizó durante la década de 2010. Entonces, para entender por qué existe, necesitamos retroceder en el tiempo.

A medida que nuestras bibliotecas y marcos evolucionaron, también lo hicieron nuestras herramientas de depuración. Por ejemplo, en los primeros días de Apache Server, los registros eran uno de los pocos métodos para depurar. A medida que llegaban las solicitudes, Apache generaba un proceso hijo y manejaba las solicitudes. Si querías depurar lo que sucedió durante esa solicitud específica, podrías simplemente extraer los registros del proceso y verás todo el flujo de operación. Y eso funcionó. Estábamos contentos. Luego obtuvimos concurrencia básica. Piensa en IIS en ASP.NET. En lugar de generar un proceso para cada solicitud, comenzamos a manejar múltiples solicitudes en un solo proceso, pero en un hilo separado. Los registros siguen siendo un buen método de depuración, pero para aislar los registros de la solicitud, necesitamos prefijarlos con el nombre del hilo y luego filtrar los mensajes de registro basándonos en él. No es gran cosa, pero lo hicimos funcionar. Luego obtuvimos concurrencia avanzada. Nuestros marcos evolucionaron a ser asíncronos, multihilos, futuros y promesas, marcos basados en bucles de eventos. Esto es Node.js. Así que ahora nuestra solicitud puede comenzar en un hilo, pero terminar en uno diferente, pasando por muchos otros hilos en el camino.

2. Reinventando la Trazabilidad Distribuida

Short description:

El prefijo de los registros con un ID único para cada solicitud ya no resuelve el problema en un sistema distribuido. Con el auge de los servicios contenerizados, los backends se distribuyen en varias máquinas, lo que dificulta el seguimiento de las operaciones. Para abordar esto, reinventamos la trazabilidad distribuida desde cero. Introdujimos el concepto de una traza, que sigue una solicitud y captura datos de depuración. Dentro de la traza, tenemos spans que representan la unidad más pequeña de trabajo, como una solicitud HTTP o una llamada a una función. Los spans pueden crear spans hijos, lo que nos permite reflejar la estructura de nuestro software. Cada span tiene un ID único y contiene datos como su ID padre.

Prefijarlos con el nombre del hilo realmente no resuelve nuestro problema ahora. Necesitamos prefijarlos con algo único para la solicitud en sí, y eso es lo que hicimos. Generamos un ID único para cada solicitud y lo prefijamos, nuestros registros.

Pero nuestros frameworks no dejaron de evolucionar. Hace unos 10 años, Docker y AWS dieron paso a los servicios contenerizados. Y ahora nuestros backends ni siquiera viven en una sola máquina. Cada contenedor y microservicio manejaba múltiples solicitudes y producía sus propios registros. Nuestros registros están por todas partes ahora. Era muy difícil entender el flujo de operaciones, por lo que necesitábamos una mejor herramienta de depuración que pudiera rastrear las operaciones a medida que saltan entre containers y servicios. Ahí es cuando la trazabilidad distribuida se convirtió en una herramienta necesaria para la depuración.

Para entender cómo funciona, vamos a reinventarlo desde cero. Dado que nuestros backends ahora tienen una naturaleza muy distribuida, necesitábamos definir un vehículo para cada solicitud que la seguirá y capturará los data de depuración en el camino. Llamemos a eso una traza. La traza comenzará cuando comience el flujo de operaciones, y va a tener un ID único. Eso puede ser el frontend, por ejemplo.

Si pensamos en los registros, generalmente nos dicen qué sucedió en un momento particular. Intentan imitar la estructura de nuestro código. Así que inventemos eso ahora. Inventemos algo que vaya a describir la unidad más pequeña de trabajo, como una solicitud HTTP o una llamada a una función o cualquier cosa específica que nuestro software haga en un momento específico. Vamos a llamar a eso un span, y vamos a crear uno inmediatamente cuando comience la traza. Eso va a ser nuestro span raíz.

Así que al igual que los registros, los spans van a imitar la estructura de nuestro software. Pero como lo estamos reinventando, hagámoslo mucho más inteligente que simples mensajes. Entonces, como los spans son la unidad más pequeña de trabajo, como una sola función, y sabemos que una función puede invocar a otra función, que a su vez también puede invocar a una tercera función, vamos a design nuestros spans para que puedan crear spans hijos, que pueden crear sus propios spans hijos y así sucesivamente. Ahora realmente podemos reflejar la estructura de nuestro software con esto. Tenemos una jerarquía de spans, pero necesitamos recordar qué span es hijo de qué span. Para hacer eso, vamos a necesitar algo para identificar cada span. Así que asignaremos un ID a cada span a medida que los creamos. También necesitamos guardar el ID del span padre. Así que vamos a crear un espacio dentro de cada span para que pueda contener data como su ID y su ID padre.

3. Mejorando los Datos de Trazabilidad y Distribuyendo la Trazabilidad

Short description:

Además de capturar datos básicos sobre los spans, también podemos mantener etiquetas y un campo de estado para proporcionar más contexto y permitir un mejor análisis. Al introducir un método de finalización, podemos calcular la duración de los spans e identificar cuellos de botella de rendimiento. Para distribuir la traza en el backend, creamos un contexto de traza que concatena el ID de la traza y el ID del último span en una cadena. Esta cadena puede ser fácilmente transferida y analizada por diferentes componentes, permitiendo una trazabilidad continua.

¿Pero por qué detenernos ahí? Tenemos espacio para más data. Mantengamos un conjunto de etiquetas para que podamos buscarlas, agregarlas y agruparlas más tarde. También mantengamos un campo de estado que va a indicar si los spans funcionan, terminan con éxito o no. Básicamente podemos mantener cualquier tipo de data que pueda ser útil más adelante.

Como sabemos cuándo los creamos, introduzcamos un método de finalización que anotará cuándo terminaron los spans. Así que ahora podemos calcular cuánto tiempo tomaron los spans. Ahora tenemos suficiente información para graficarlos. Y si lo hacemos, vamos a poder identificar fácilmente los cuellos de botella de performance. Quiero decir, será obvio que ese span no debería tomar tanto tiempo.

Pero aún así, ¿cómo distribuimos esto ahora? ¿Cómo podemos continuar esta traza en el backend? Teníamos la traza y su ID. También tenemos un montón de spans adjuntos a ella. Creemos un contexto de traza que va a concatenar el ID de la traza y el ID del último span en una cadena. Ahora podemos transferir esta cadena para que nuestro backend o las próximas unidades de procesamiento puedan analizarla y continuar la trazabilidad, comenzando desde el último span. Como va a ser una cadena, podemos transferirla fácilmente, ya sea un cliente, un microservicio, un trabajo cron, o esté en JavaScript o Python o PHP, siempre y cuando pueda analizar y leer una cadena, puede continuar nuestra traza. Y eso es trazabilidad distribuida. Así es como podemos trazar todo nuestro sistema, sin importar cuán complejo sea.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

A Guide to React Rendering Behavior
React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
Speeding Up Your React App With Less JavaScript
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Top Content
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.
React Concurrency, Explained
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
Top Content
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar
The Future of Performance Tooling
JSNation 2022JSNation 2022
21 min
The Future of Performance Tooling
Top Content
Our understanding of performance & user-experience has heavily evolved over the years. Web Developer Tooling needs to similarly evolve to make sure it is user-centric, actionable and contextual where modern experiences are concerned. In this talk, Addy will walk you through Chrome and others have been thinking about this problem and what updates they've been making to performance tools to lower the friction for building great experiences on the web.
Optimizing HTML5 Games: 10 Years of Learnings
JS GameDev Summit 2022JS GameDev Summit 2022
33 min
Optimizing HTML5 Games: 10 Years of Learnings
Top Content
The open source PlayCanvas game engine is built specifically for the browser, incorporating 10 years of learnings about optimization. In this talk, you will discover the secret sauce that enables PlayCanvas to generate games with lightning fast load times and rock solid frame rates.
When Optimizations Backfire
JSNation 2023JSNation 2023
26 min
When Optimizations Backfire
Top Content
Ever loaded a font from the Google Fonts CDN? Or added the loading=lazy attribute onto an image? These optimizations are recommended all over the web – but, sometimes, they make your app not faster but slower.
In this talk, Ivan will show when some common performance optimizations backfire – and what we need to do to avoid that.

Workshops on related topic

React Performance Debugging Masterclass
React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
Featured WorkshopFree
Ivan Akulov
Ivan Akulov
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
Building WebApps That Light Up the Internet with QwikCity
JSNation 2023JSNation 2023
170 min
Building WebApps That Light Up the Internet with QwikCity
Featured WorkshopFree
Miško Hevery
Miško Hevery
Building instant-on web applications at scale have been elusive. Real-world sites need tracking, analytics, and complex user interfaces and interactions. We always start with the best intentions but end up with a less-than-ideal site.
QwikCity is a new meta-framework that allows you to build large-scale applications with constant startup-up performance. We will look at how to build a QwikCity application and what makes it unique. The workshop will show you how to set up a QwikCitp project. How routing works with layout. The demo application will fetch data and present it to the user in an editable form. And finally, how one can use authentication. All of the basic parts for any large-scale applications.
Along the way, we will also look at what makes Qwik unique, and how resumability enables constant startup performance no matter the application complexity.
Next.js 13: Data Fetching Strategies
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
Alice De Mauro
Alice De Mauro
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
React Performance Debugging
React Advanced Conference 2023React Advanced Conference 2023
148 min
React Performance Debugging
Workshop
Ivan Akulov
Ivan Akulov
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
Maximize App Performance by Optimizing Web Fonts
Vue.js London 2023Vue.js London 2023
49 min
Maximize App Performance by Optimizing Web Fonts
WorkshopFree
Lazar Nikolov
Lazar Nikolov
You've just landed on a web page and you try to click a certain element, but just before you do, an ad loads on top of it and you end up clicking that thing instead.
That…that’s a layout shift. Everyone, developers and users alike, know that layout shifts are bad. And the later they happen, the more disruptive they are to users. In this workshop we're going to look into how web fonts cause layout shifts and explore a few strategies of loading web fonts without causing big layout shifts.
Table of Contents:What’s CLS and how it’s calculated?How fonts can cause CLS?Font loading strategies for minimizing CLSRecap and conclusion
High-performance Next.js
React Summit 2022React Summit 2022
50 min
High-performance Next.js
Workshop
Michele Riva
Michele Riva
Next.js is a compelling framework that makes many tasks effortless by providing many out-of-the-box solutions. But as soon as our app needs to scale, it is essential to maintain high performance without compromising maintenance and server costs. In this workshop, we will see how to analyze Next.js performances, resources usage, how to scale it, and how to make the right decisions while writing the application architecture.