Service Tracing, OpenTracing è Jaeger

Service Tracing, OpenTracing è Jaeger

Utilizemu l'architettura di microserviziu in i nostri prughjetti. Quandu si verificanu i colli di bottiglia di rendiment, assai tempu hè passatu per monitorà è analizà i logs. Quandu si registranu i timings di l'operazioni individuali in un schedariu di log, hè di solitu difficiuli di capisce ciò chì hà purtatu à l'invucazione di queste operazioni, per seguità a sequenza di l'azzioni o u cambiamentu di u tempu di una operazione relative à l'altru in diversi servizii.

Per minimizzà u travagliu manuale, avemu decisu di utilizà unu di i strumenti di traccia. Circa cumu è perchè pudete aduprà traccia è cumu l'avemu fattu, è serà discutitu in questu articulu.

Chì prublemi ponu esse risolti cù traccia

  1. Truvate i colli di bottiglia di rendiment sia in un serviziu unicu sia in tuttu l'arburu di esecutivu trà tutti i servizii participanti. Per esempiu:
    • Molti brevi chjamati consecutivi trà servizii, per esempiu, à geocoding o à una basa di dati.
    • Longu I / O aspetta, cum'è trasferimenti di rete o letture di discu.
    • Long parsing di dati.
    • Operazioni longu chì necessitanu cpu.
    • Sezzioni di codice chì ùn sò micca necessarii per ottene u risultatu finali è ponu esse eliminati o ritardati.
  2. Capisce chjaramente in quale sequenza ciò chì hè chjamatu è ciò chì succede quandu l'operazione hè realizata.
    Service Tracing, OpenTracing è Jaeger
    Pò esse vistu chì, per esempiu, u Request hè ghjuntu à u serviziu WS -> u serviziu WS hà aghjustatu dati attraversu u serviziu R -> dopu mandatu una dumanda à u serviziu V -> u serviziu V hà carricatu assai dati da u R. serviziu -> andò à u serviziu P -> u serviziu P si n'andò di novu à u serviziu R -> u serviziu V ignorò u risultatu è andò à u serviziu J -> è solu dopu vultò a risposta à u serviziu WS, mentre cuntinueghja à calculà qualcosa altru in u fondo.
    Senza una tale traccia o documentazione dettagliata per tuttu u prucessu, hè assai difficiuli di capisce ciò chì succede quandu si vede u codice per a prima volta, è u codice hè spargugliatu in diversi servizii è ammucciatu daretu à una mansa di bins è interfaccia.
  3. Raccolta di informazioni nantu à l'arburu di l'esekzione per l'analisi differita sussegwenti. In ogni tappa di l'esekzione, pudete aghjunghje l'infurmazioni à a traccia chì hè dispunibule in questa fase è poi scopre quale dati di input hà purtatu à un scenariu simili. Per esempiu:
    • ID d'utilizatore
    • Diritti
    • Tipu di metudu sceltu
    • Errore di logu o di esecuzione
  4. Trasformendu e tracce in un subset di metrica è più analisi digià in forma di metrica.

Chì traccia pò logu. Span

In traccia ci hè u cuncettu di un span, questu hè un analogu di un logu, à a cunsola. U spa hà:

  • Nome, di solitu u nome di u metudu chì hè statu eseguitu
  • U nome di u serviziu in quale u span hè statu generatu
  • ID unicu propiu
  • Qualchì tipu di meta infurmazione in a forma di una chjave / valore chì hè stata loggata in questu. Per esempiu, i paràmetri di u metudu o u metudu finiscinu cù un errore o micca
  • Tempi di iniziu è di fine per questu span
  • ID span parenti

Ogni span hè mandatu à u cullettivu di span per esse guardatu in a basa di dati per una rivisione più tardi appena hà finitu a so esecuzione. In u futuru, pudete custruisce un arbre di tutti i spazii cunnettendu per l'id parent. Quandu analizà, pudete truvà, per esempiu, tutti i spazii in qualchì serviziu chì hà pigliatu più di qualchì tempu. In più, andendu à un spaziu specificu, vede l'arbulu tutale sopra è sottu à questu span.

Service Tracing, OpenTracing è Jaeger

Opentrace, Jagger è cumu l'avemu implementatu per i nostri prughjetti

Ci hè un standard cumuni traccia aperta, chì descrive cumu è ciò chì deve esse recullatu, senza esse ligatu da traccia à una implementazione specifica in ogni lingua. Per esempiu, in Java, tuttu u travagliu cù tracce hè realizatu per mezu di l'API Opentrace cumuni, è sottu, per esempiu, Jaeger o una implementazione predeterminata viota chì ùn faci nunda pò esse oculata.
Avemu aduprà Jaeger cum'è una implementazione di Opentrace. Hè custituitu di parechji cumpunenti:

Service Tracing, OpenTracing è Jaeger

  • Jaeger-agent hè un agentu lucale chì hè generalmente installatu in ogni macchina è i servizii sò logati in questu in u portu predeterminatu locale. Se ùn ci hè micca un agentu, e tracce di tutti i servizii nantu à sta macchina sò generalmente disattivati
  • Jaeger-collector - tutti l'agenti mandanu tracce cullette à ellu, è li mette in a basa di dati selezziunata
  • A basa di dati hè a so cassandra preferita, ma usemu elasticsearch, ci sò implementazioni per un paru di altre basa di dati è una implementazione in memoria chì ùn salva nunda à u discu.
  • Jaeger-query hè un serviziu chì và à a basa di dati è torna tracce digià cullate per l'analisi
  • Jaeger-ui hè una interfaccia web per a ricerca è a visualizazione di tracce, va à jaeger-query

Service Tracing, OpenTracing è Jaeger

Un cumpunente separatu pò esse chjamatu l'implementazione di l'opentrace jaeger per lingue specifiche, attraversu quale spans sò mandati à jaeger-agent.
Cunnettendu Jagger in Java vene à implementà l'interfaccia io.opentracing.Tracer, dopu chì tutte e tracce à traversu volaranu à l'agente reale.

Service Tracing, OpenTracing è Jaeger

Ancu per u cumpunente di primavera, pudete cunnette opentracing-spring-cloud-starter è implementazione da Jaeger opentracing-spring-jaeger-cloud-starter chì cunfigurà automaticamente a traccia per tuttu ciò chì passa per questi cumpunenti, per esempiu http richieste à i cuntrolli, dumande à a basa di dati attraversu jdbc, etc.

Logging di traccia in Java

In un locu à u livellu superiore, u primu Span deve esse creatu, questu pò esse fattu automaticamente, per esempiu, da u controller di primavera quandu una dumanda hè ricevutu, o manualmente s'ellu ùn ci hè nimu. Hè tandu trasmessu attraversu u Scope sottu. Se qualcunu di i metudi quì sottu volenu aghjunghje un Span, piglia l'attuale ActiveSpan da u Scope, crea un novu Span è dice chì u so parente hè l'activeSpan risultante, è face u novu Span attivu. Quandu chjamanu servizii esterni, u span attivu attuale hè passatu à elli, è quelli servizii creanu novi spazii cù riferimentu à questu span.
Tuttu u travagliu passa per l'istanza Tracer, pudete uttene per mezu di u mecanismu DI, o GlobalTracer.get () cum'è una variabile globale se u mecanismu DI ùn funziona micca. Per automaticamente, se u tracciante ùn hè micca inizializatu, NoopTracer torna chì ùn faci nunda.
In più, u scopu attuale hè ottenutu da u tracciatore attraversu u ScopeManager, un novu scopu hè creatu da u currente cù un ligame di u novu span, è dopu u Scope creatu hè chjusu, chì chjude u span creatu è torna u Scope precedente à u statu attivu. Scope hè ligatu à un filu, cusì quandu a prugrammazione multi-threaded, ùn deve micca scurdate di trasferisce u span attivu à un altru filu, per più attivazione di u Scope di un altru filu cù riferimentu à questu span.

io.opentracing.Tracer tracer = ...; // GlobalTracer.get()

void DoSmth () {
   try (Scope scope = tracer.buildSpan("DoSmth").startActive(true)) {
      ...
   }
}
void DoOther () {
    Span span = tracer.buildSpan("someWork").start();
    try (Scope scope = tracer.scopeManager().activate(span, false)) {
        // Do things.
    } catch(Exception ex) {
        Tags.ERROR.set(span, true);
        span.log(Map.of(Fields.EVENT, "error", Fields.ERROR_OBJECT, ex, Fields.MESSAGE, ex.getMessage()));
    } finally {
        span.finish();
    }
}

void DoAsync () {
    try (Scope scope = tracer.buildSpan("ServiceHandlerSpan").startActive(false)) {
        ...
        final Span span = scope.span();
        doAsyncWork(() -> {
            // STEP 2 ABOVE: reactivate the Span in the callback, passing true to
            // startActive() if/when the Span must be finished.
            try (Scope scope = tracer.scopeManager().activate(span, false)) {
                ...
            }
        });
    }
}

Per a prugrammazione multi-threaded, ci hè ancu TracedExecutorService è wrappers simili chì trasmette automaticamente u span attuale à u filu quandu i travaglii asincroni sò lanciati:

private ExecutorService executor = new TracedExecutorService(
    Executors.newFixedThreadPool(10), GlobalTracer.get()
);

Per richieste http esterne ci hè TracingHttpClient

HttpClient httpClient = new TracingHttpClientBuilder().build();

I prublemi chì avemu affruntatu

  • Beans è DI ùn sò micca sempre u travagliu se u tracciante ùn hè micca usatu in un serviziu o cumpunente, allora Autowired Tracer ùn pò micca travaglià è avete da aduprà GlobalTracer.get ().
  • L'annotazioni ùn funziona micca s'ellu ùn hè micca un cumpunente o serviziu, o se u metudu hè chjamatu da un metudu vicinu di a stessa classe. Avete da esse attentu à verificà ciò chì funziona è aduprà a creazione manuale di traccia se @Traced ùn funziona micca. Pudete ancu aghjunghje un compilatore supplementu per l'annotazioni java, allora duveranu travaglià in ogni locu.
  • In u vechju di primavera è di primavera, l'autoconfiguration opentraing di nuvola di primavera ùn funziona micca per via di bugs in DI, allora se vulete chì e tracce in i cumpunenti di primavera funzionanu automaticamente, pudete fà per analogia cù github.com/opentracing-contrib/java-spring-jaeger/blob/master/opentracing-spring-jaeger-starter/src/main/java/io/opentracing/contrib/java/spring/jaeger/starter/JaegerAutoConfiguration.java
  • Pruvate cù risorse ùn funziona micca in groovy, duvete aduprà pruvà infine.
  • Ogni serviziu deve avè u so propiu spring.application.name sottu à quale e tracce seranu registrate. Chì faci un nome separatu per a vendita è a prova, per ùn interferiscenu micca cun elli.
  • Se utilizate GlobalTracer è tomcat, allora tutti i servizii chì funzionanu in questu tomcat anu un GlobalTracer, perchè tutti anu u listessu nome di serviziu.
  • Quandu aghjunghje tracce à un metudu, deve esse sicuru chì ùn hè micca chjamatu parechje volte in un ciclu. Hè necessariu aghjunghje una traccia cumuna per tutte e chjama, chì guarantisci u tempu di travagliu tutale. Altrimenti, una carica eccessiva serà creata.
  • Una volta in jaeger-ui, dumande troppu grande sò state fatte per un gran numaru di tracce, è postu ch'elli ùn aspittàvanu micca una risposta, anu fattu di novu. In u risultatu, jaeger-query hà cuminciatu à manghjà assai memoria è rallentà elastica. Aiutatu da riavvià jaeger-query

Campionamentu, almacenamentu è vede tracce

Ci sò trè tippi tracce di campionamentu:

  1. Const chì manda è salva tutte e tracce.
  2. Probabilisticu chì filtra tracce cù una certa probabilità data.
  3. Ratelimiting chì limita u numeru di tracce per seconda. Pudete cunfigurà sti paràmetri nantu à u cliente, sia in u jaeger-agent sia in u cullettore. Avà usemu const 1 in a pila di valutatore, postu chì ùn sò micca assai richieste, ma piglianu assai tempu. In u futuru, se questu eserciterà una carica eccessiva nantu à u sistema, pudete limità.

Sè vo aduprate Cassandra, da manera predeterminata, guarda solu tracce per dui ghjorni. Avemu aduprà elasticsearch e tracce sò guardati per tuttu u tempu è ùn sò micca sguassati. Un indice separatu hè creatu per ogni ghjornu, per esempiu jaeger-service-2019-03-04. In u futuru, avete bisognu di cunfigurà a pulizia automatica di vechji tracce.

Per vede e tracce avete bisognu:

  • Selezziunate u serviziu da quale vulete filtrà e tracce, per esempiu, tomcat7-default per un serviziu chì hè in esecuzione in u tomcat è ùn pò micca avè u so nome.
  • Allora selezziunate l'operazione, l'intervallu di tempu è u tempu minimu di operazione, per esempiu da 10 seconde, per piglià solu esecuzioni longu.
    Service Tracing, OpenTracing è Jaeger
  • Andate à una di e tracce è vede ciò chì rallentava quì.
    Service Tracing, OpenTracing è Jaeger

Inoltre, s'ellu hè cunnisciutu qualchì id di dumanda, pudete truvà una traccia da questu id per mezu di una ricerca di tag, se questu id hè registratu in u span di traccia.

Documentazione

articuli

Видео

Source: www.habr.com

Add a comment