Controlla i tuoi servizi con OTEL, Jaeger e Prometheus

Discutiamo una questione importante: come monitoriamo i nostri servizi in caso di problemi?

Da una parte, abbiamo Prometheus con gli alert e Kibana per i cruscotti e altre utili funzionalità. Sappiamo anche come raccogliere i log — lo stack ELK è la nostra soluzione di riferimento. Tuttavia, la semplice registrazione non è sempre sufficiente: non fornisce una visione completa del percorso di una richiesta attraverso l’intero ecosistema dei componenti.

Puoi trovare ulteriori informazioni su ELK qui.

Ma cosa succede se vogliamo visualizzare le richieste? E se dobbiamo correlare le richieste che viaggiano tra i sistemi? Questo vale sia per i microservizi che per i monoliti — non importa quanti servizi abbiamo; ciò che conta è come gestiamo la loro latenza.

Infatti, ogni richiesta utente potrebbe passare attraverso una catena completa di servizi indipendenti, database, code di messaggi e API esterne.

In un ambiente così complesso, diventa estremamente difficile individuare esattamente dove si verificano ritardi, identificare quale parte della catena agisce come collo di bottiglia delle prestazioni e trovare rapidamente la causa principale dei guasti quando si verificano.

Per affrontare efficacemente queste sfide, abbiamo bisogno di un sistema centralizzato e coerente per raccogliere dati di telemetria — tracce, metriche e log. È qui che OpenTelemetry e Jaeger vengono in nostro soccorso.

Diamo un’occhiata ai Fondamentali

Ci sono due termini principali che dobbiamo capire:

ID Traccia

Un ID Traccia è un identificatore di 16 byte, spesso rappresentato come una stringa esadecimale di 32 caratteri. Viene generato automaticamente all’inizio di una traccia e rimane lo stesso attraverso tutti i segmenti creati da una particolare richiesta. Questo rende facile vedere come una richiesta viaggia attraverso diversi servizi o componenti in un sistema.

ID Segmento

Ogni singola operazione all’interno di una traccia ottiene il proprio ID Segmento, che è tipicamente un valore di 64 bit generato casualmente. I segmenti condividono lo stesso ID Traccia, ma ognuno ha un ID Segmento unico, in modo da poter individuare esattamente quale parte del flusso di lavoro rappresenta ciascun segmento (come una query al database o una chiamata a un altro microservizio).

Come Sono Relazionati?

ID Traccia e ID Segmento si integrano reciprocamente. 

Quando una richiesta viene avviata, viene generato un ID Traccia e passato a tutti i servizi coinvolti. Ciascun servizio, a sua volta, crea un segmento con un ID Segmento unico collegato all’ID Traccia, consentendo di visualizzare l’intero ciclo di vita della richiesta dall’inizio alla fine.

Ok, quindi perché non usare semplicemente Jaeger? Perché abbiamo bisogno di OpenTelemetry (OTEL) e di tutte le sue specifiche? È una ottima domanda! Esaminiamola passo dopo passo.

Scopri di più su Jaeger qui.

TL;DR

  • Jaeger è un sistema per memorizzare e visualizzare tracce distribuite. Raccoglie, memorizza, cerca e visualizza i dati che mostrano come le richieste “viaggiano” attraverso i tuoi servizi.
  • OpenTelemetry (OTEL) è uno standard (e un insieme di librerie) per raccogliere dati di telemetria (tracce, metriche, log) dalle tue applicazioni e infrastrutture. Non è legato a uno strumento di visualizzazione o backend singolo.

In poche parole:

  • OTEL è come un “linguaggio universale” e un insieme di librerie per la raccolta di telemetria.
  • Jaeger è un backend e un’interfaccia utente per visualizzare e analizzare tracce distribuite.

Perché Abbiamo Bisogno di OTEL se Abbiamo Già Jaeger?

1. Uno Standard Unico per la Raccolta

In passato, c’erano progetti come OpenTracing e OpenCensus. OpenTelemetry unifica questi approcci alla raccolta di metriche e tracce in uno standard universale.

2. Facile Integrazione

Scrivi il tuo codice in Go (o un altro linguaggio), aggiungi le librerie OTEL per l’autoinserimento di intercettori e span, e il gioco è fatto. Dopo, non importa dove vuoi inviare quei dati—Jaeger, Tempo, Zipkin, Datadog, un backend personalizzato—OpenTelemetry si occupa della parte tecnica. Devi solo sostituire l’esportatore.

3. Non Solo Tracce

OpenTelemetry gestisce tracce, ma si occupa anche di metriche e log. Ottieni un unico set di strumenti per tutte le tue esigenze di telemetria, non solo il tracciamento.

4. Jaeger Come Backend

Jaeger è una scelta eccellente se sei principalmente interessato alla visualizzazione del tracciamento distribuito. Ma non fornisce l’strumentazione cross-language di default. OpenTelemetry, d’altra parte, ti offre un modo standardizzato per raccogliere dati, e poi decidi dove inviarli (compreso Jaeger).

In pratica, spesso lavorano insieme:

La tua applicazione utilizza OpenTelemetry → comunica tramite protocollo OTLP → passa al Collettore OpenTelemetry (HTTP o grpc) → esporta a Jaeger per la visualizzazione.


Parte Tecnica

Design di Sistema (Un Po’)

Proviamo rapidamente a delineare un paio di servizi che faranno quanto segue:

  1. Servizio Acquisto – elabora un pagamento e lo registra in MongoDB
  2. CDC con Debezium – ascolta i cambiamenti nella tabella MongoDB e li invia a Kafka
  3. Processore di Acquisti – consuma il messaggio da Kafka e chiama il Servizio di Autenticazione per cercare l’user_id per la convalida
  4. Servizio di Autenticazione – un semplice servizio utente

In sintesi:

  • 3 servizi Go
  • Kafka
  • CDC (Debezium)
  • MongoDB

Parte del Codice

Cominciamo con l’infrastruttura. Per collegare tutto in un unico sistema, creeremo un ampio file Docker Compose. Inizieremo configurando la telemetria.

Nota: Tutto il codice è disponibile tramite un link alla fine dell’articolo, compresa l’infrastruttura.

YAML

 

Configureremo anche il raccoglitore, il componente che raccoglie telemetria.

Qui scegliamo gRPC per il trasferimento dati, il che significa che la comunicazione avverrà tramite HTTP/2:

YAML

 

Assicurati di adattare eventuali indirizzi come necessario, e hai completato la configurazione di base.

Sappiamo già che OpenTelemetry (OTEL) utilizza due concetti chiave — ID traccia e ID span — che aiutano a tracciare e monitorare le richieste nei sistemi distribuiti.

Implementazione del Codice

Ora, vediamo come far funzionare tutto nel tuo codice Go. Abbiamo bisogno degli import seguenti:

Go

 

Quindi, aggiungiamo una funzione per inizializzare il nostro tracer in main() quando l’applicazione si avvia:

Go

 

Con il tracciamento impostato, dobbiamo solo inserire span nel codice per tracciare le chiamate. Ad esempio, se vogliamo misurare le chiamate al database (poiché di solito è il primo posto in cui cerchiamo problemi di prestazioni), possiamo scrivere qualcosa del genere:

Go

 

Abbiamo il tracciamento a livello di servizio — ottimo! Ma possiamo andare ancora più a fondo, strumentando il livello del database:

Go

 

Ora abbiamo una visione completa del percorso della richiesta. Vai all’interfaccia utente di Jaeger, cerca gli ultimi 20 tracciati sotto servizio-auth, e vedrai tutti gli span e come si collegano in un unico punto.

Ora, tutto è visibile. Se hai bisogno, puoi includere l’intera query nei tag. Tuttavia, ricorda di non sovraccaricare la telemetria: aggiungi i dati in modo deliberato. Sto semplicemente dimostrando cosa è possibile, ma includere l’intera query in questo modo non è qualcosa che generalmente raccomanderei.

client-server gRPC

Se vuoi vedere un tracciato che coinvolge due servizi gRPC, è piuttosto semplice. Tutto ciò di cui hai bisogno è aggiungere gli interceptor pronti all’uso dalla libreria. Ad esempio, sul lato server:

Go

 

Sul lato client, il codice è altrettanto breve:

Go

 

Ecco fatto! Assicurati che i tuoi esportatori siano configurati correttamente e vedrai un singolo ID di tracciamento registrato attraverso questi servizi quando il client chiama il server.

Gestione degli eventi del CDC e tracciamento

Vuoi gestire anche gli eventi del CDC? Un approccio semplice è incorporare l’ID di tracciamento nell’oggetto che MongoDB memorizza. In questo modo, quando Debezium cattura il cambiamento e lo invia a Kafka, l’ID di tracciamento fa già parte del record.

Ad esempio, se stai usando MongoDB, puoi fare qualcosa del genere:

Go

 

Debzium quindi rileva questo oggetto (incluso il trace_id) e lo invia a Kafka. Sul lato del consumatore, devi semplicemente analizzare il messaggio in arrivo, estrarre il trace_id e unirlo nel tuo contesto di tracciamento:

Go

 

Go

 

Alternativa: Utilizzare gli Header di Kafka

A volte è più semplice memorizzare l’ID di tracciamento negli header di Kafka piuttosto che nel payload stesso. Per i flussi di lavoro CDC, questo potrebbe non essere disponibile di default – Debezium può limitare ciò che viene aggiunto agli header. Ma se controlli il lato produttore (o se stai utilizzando un produttore standard di Kafka), puoi fare qualcosa del genere con Sarama:

Inserire un ID di tracciamento negli Header

Go

 

Estrarre un ID di tracciamento sul lato consumatore

Go

 

A seconda del tuo caso d’uso e di come è configurato il tuo pipeline CDC, puoi scegliere l’approccio che funziona meglio:

  1. Incorpora l’ID di tracciamento nel record del database affinché fluisca naturalmente tramite CDC.
  2. Utilizza gli header di Kafka se hai più controllo sul lato produttore o se desideri evitare di gonfiare il payload del messaggio.

In entrambi i casi, puoi mantenere coerenti i tuoi tracciati attraverso più servizi, anche quando gli eventi vengono elaborati in modo asincrono tramite Kafka e Debezium.

Conclusione

Utilizzare OpenTelemetry e Jaeger fornisce tracciature dettagliate delle richieste, aiutandoti a individuare dove e perché si verificano ritardi nei sistemi distribuiti.

Aggiungere Prometheus completa il quadro con metriche – indicatori chiave delle prestazioni e della stabilità. Insieme, questi strumenti formano un completo stack di osservabilità, consentendo una più rapida individuazione e risoluzione dei problemi, ottimizzazione delle prestazioni e affidabilità complessiva del sistema.

Posso dire che questo approccio accelera significativamente il troubleshooting in un ambiente di microservizi ed è una delle prime cose che implementiamo nei nostri progetti.

Links

Source:
https://dzone.com/articles/control-services-otel-jaeger-prometheus