Service Tracing, OpenTracing eta Jaeger

Service Tracing, OpenTracing eta Jaeger

Gure proiektuetan mikrozerbitzuen arkitektura erabiltzen dugu. Errendimendu-botoiak gertatzen direnean, denbora asko ematen da erregistroak kontrolatzen eta analizatzen. Erregistro-fitxategi batean banakako eragiketen denborak erregistratzean, normalean zaila da ulertzea zerk eragin duen eragiketa horiek deitzea, ekintzen sekuentzia edo eragiketa baten denbora-aldaketaren jarraipena egitea zerbitzu desberdinetan.

Eskuzko lana gutxitzeko, trazatzeko tresnetako bat erabiltzea erabaki genuen. Trazadura nola eta zergatik erabil dezakezun eta nola egin genuen buruz, eta artikulu honetan eztabaidatuko da.

Zer arazo konpon daitezkeen trazadurarekin

  1. Bilatu errendimendu-botoiak zerbitzu bakar baten barruan eta parte hartzen duten zerbitzu guztien arteko exekuzio zuhaitz osoan. Adibidez:
    • Zerbitzuen arteko jarraian dei labur asko, adibidez, geokodeketara edo datu-base batera.
    • I/O itxaronaldi luzeak, hala nola sareko transferentziak edo diskoen irakurketak.
    • Datuen analisi luzea.
    • CPU behar duten eragiketa luzeak.
    • Azken emaitza lortzeko beharrezkoak ez diren eta kendu edo atzeratu daitezkeen kode-atalak.
  2. Argi ulertzea zer sekuentziatan zer deitzen den eta zer gertatzen den eragiketa egiten denean.
    Service Tracing, OpenTracing eta Jaeger
    Ikusten da, adibidez, Eskaera WS zerbitzura iritsi zela -> WS zerbitzuak R zerbitzuaren bidez datuak gehitu zituen -> gero eskaera bat bidali zuen V zerbitzura -> V zerbitzuak R-tik datu asko kargatu zituela zerbitzua -> P zerbitzura joan zen -> P zerbitzua berriro R zerbitzura joan zen -> V zerbitzuak emaitzari ez zion jaramonik egin eta J zerbitzura joan zen -> eta orduan bakarrik itzuli zuen erantzuna WS zerbitzura, beste zerbait kalkulatzen jarraitu zuen bitartean. atzeko planoa.
    Prozesu osorako halako aztarnarik edo dokumentazio zehatzik gabe, oso zaila da kodea lehen aldiz begiratzen duzunean zer gertatzen den ulertzea, eta kodea zerbitzu ezberdinetan sakabanatuta dago eta edukiontzi eta interfaze mordo baten atzean ezkutatzen da.
  3. Exekuzio-zuhaitzari buruzko informazioa biltzea, gerora analisia egiteko. Exekuzioaren fase bakoitzean, fase honetan eskuragarri dagoen arrastoari informazioa gehi diezaiokezu eta, ondoren, asma dezakezu zer sarrerako datuek antzeko eszenatoki batera eraman zuten. Adibidez:
    • Erabiltzaile IDa
    • Eskubide
    • Hautatutako metodo mota
    • Erregistroa edo exekuzio-errorea
  4. Arrastoak metrika azpimultzo batean bihurtzea eta analisi gehiago dagoeneko metrika moduan.

Zein arrasto erregistratu daitekeen. Tarte

Trazatzean span kontzeptua dago, hau erregistro baten analogoa da, kontsolarentzat. Bainuetxeak honako hauek ditu:

  • Izena, normalean exekutatu den metodoaren izena
  • Tartea sortu den zerbitzuaren izena
  • Nortasun-identifikazio bakarra
  • Metainformazio moduko bat, bertan saioa hasi den gako/balio baten moduan. Adibidez, metodoaren parametroak edo metodoa akats batekin amaitu zen edo ez
  • Tarte honen hasiera eta amaiera orduak
  • Gurasoen tartearen IDa

Tarte bakoitza span-biltzailera bidaltzen da datu-basean gordetzeko, gero berrikusteko, exekuzioa amaitu bezain laster. Etorkizunean, tarte guztietako zuhaitza eraiki dezakezu gurasoen IDaren bidez konektatuz. Aztertzerakoan, adibidez, denbora pixka bat baino gehiago behar izan duten zerbitzu batzuetan tarte guztiak aurki ditzakezu. Gainera, tarte zehatz batera joanez, ikusi zuhaitz osoa tarte honen gainean eta azpian.

Service Tracing, OpenTracing eta Jaeger

Opentrace, Jagger eta nola inplementatu genuen gure proiektuetarako

Estandar komun bat dago traza irekia, nola eta zer bildu behar den deskribatzen duena, edozein hizkuntzatan inplementazio zehatz bati lotu gabe. Adibidez, Javan, aztarnak dituzten lan guztiak Opentrace API arruntaren bidez egiten dira, eta haren azpian, adibidez, Jaeger edo ezer egiten ez duen inplementazio lehenetsi huts bat ezkutatu daiteke.
Erabiltzen ari gara Jaeger Opentrace-ren ezarpen gisa. Hainbat osagaiz osatuta dago:

Service Tracing, OpenTracing eta Jaeger

  • Jaeger-agent makina bakoitzean instalatu ohi den tokiko agente bat da eta zerbitzuak bertan sartzen dira tokiko ataka lehenetsian. Agenterik ez badago, makina honetako zerbitzu guztien arrastoak normalean desgaitu egiten dira
  • Jaeger-biltzailea - agente guztiek bildutako aztarnak bidaltzen dizkiote eta hautatutako datu-basean jartzen ditu
  • Datu-basea da haien kasandra hobetsi, baina elastiko bilaketa erabiltzen dugu, beste datu-base pare baterako inplementazioak daude eta diskoan ezer gordetzen ez duen memorian inplementazio bat dago.
  • Jaeger-query datu-basera doan zerbitzu bat da eta dagoeneko bildutako arrastoak itzultzen ditu aztertzeko
  • Jaeger-ui arrastoak bilatzeko eta ikusteko web interfazea da, jaeger-query-ra doa.

Service Tracing, OpenTracing eta Jaeger

Osagai bereizi bati opentrace jaeger-en inplementazioa dei daiteke lengoaia zehatzetarako, zeinaren bidez tarteak jaeger-agent-era bidaltzen diren.
Jagger konektatzen Javan io.opentracing.Tracer interfazea inplementatzera dator eta, ondoren, haren bidezko aztarna guztiak benetako agentera joango dira.

Service Tracing, OpenTracing eta Jaeger

Udaberriko osagairako ere konektatu zaitezke opentracing-udaberria-hodeia-hasiera eta Jaegerren ezarpena opentracing-spring-jaeger-cloud-starter osagai horietatik pasatzen den guztiaren traza automatikoki konfiguratuko duena, adibidez kontrolatzaileei http eskaerak, datu-baseari jdbc bidez egindako eskaerak, etab.

Aztarnak saioa Javan

Goiko mailan, lehen Span sortu behar da, hau automatikoki egin daiteke, adibidez, udaberriko kontrolagailuak eskaera jasotzen duenean, edo eskuz ez badago. Ondoren, beheko Esparruaren bidez transmititzen da. Beheko metodoren batek Span bat gehitu nahi badu, uneko ActiveSpan hartzen du Eremutik, Span berri bat sortzen du eta bere gurasoa ondoriozko ActiveSpan dela dio eta Span berria aktibo bihurtzen du. Kanpoko zerbitzuei deitzean, uneko tarte aktiboa pasatzen zaie, eta zerbitzu horiek tarte berriak sortzen dituzte tarte horri erreferentzia eginez.
Lan guztia Tracer instantziatik pasatzen da, DI mekanismoaren bidez lor dezakezu edo GlobalTracer.get () aldagai global gisa DI mekanismoak funtzionatzen ez badu. Lehenespenez, tracer hasieratu ez bada, NoopTracer-ek ezer egiten ez duena itzuliko da.
Gainera, uneko esparrua trazatzailetik lortzen da ScopeManager-en bidez, uneko esparru berri bat sortzen da tarte berriaren lotura batekin, eta, ondoren, sortutako esparrua ixten da, eta horrek sortutako tartea ixten du eta aurreko esparrua itzultzen du. egoera aktiboa. Eremua hari bati lotuta dago, beraz, hari anitzeko programazioan, ez duzu ahaztu behar tarte aktiboa beste hari batera transferitzea, tarte honi erreferentzia eginez beste hari baten Eremua gehiago aktibatzeko.

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)) {
                ...
            }
        });
    }
}

Hari anitzeko programaziorako, TracedExecutorService eta antzeko bilgarriak ere badago uneko tartea harira automatikoki birbidaltzen duten zeregin asinkronoak abiarazten direnean:

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

Kanpoko http eskaeretarako badago TracingHttpClient

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

Aurre egin genion arazoak

  • Babarrunak eta DIk ez dute beti funtzionatzen trazatzailea zerbitzu edo osagai batean erabiltzen ez bada, orduan Automatikoki kableatua Baliteke Tracer-ek ez funtzionatzea eta GlobalTracer.get() erabili beharko duzu.
  • Oharpenek ez dute funtzionatzen osagai edo zerbitzu bat ez bada, edo metodoari klase bereko aldameneko metodo batetik deitzen bazaio. Kontuz ibili behar duzu zer funtzionatzen duen egiaztatzeko eta eskuzko arrastoen sorrera erabiltzeko @Traced-ek funtzionatzen ez badu. Java oharpenetarako konpilatzaile gehigarri bat ere erantsi dezakezu, gero nonahi funtzionatu beharko lukete.
  • Udaberriko eta udaberriko abio zaharrean, opentraing udaberriko hodeiaren autokonfigurazioak ez du funtzionatzen DI-n akatsen ondorioz, orduan udaberriko osagaietako aztarnak automatikoki funtzionatzea nahi baduzu, analogiarekin egin dezakezu. 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
  • Saiatu baliabideekin ez du funtzionatzen groovy-n, saiatu erabili behar duzu azkenik.
  • Zerbitzu bakoitzak bere udaberria.aplikazioa.izena izan behar du zeinaren azpian arrastoak erregistratuko diren. Zer egiten du salmentarako eta probarako izen bereizi bat, elkarrekin ez oztopatzeko.
  • GlobalTracer eta tomcat erabiltzen badituzu, tomcat honetan exekutatzen diren zerbitzu guztiek GlobalTracer bat dute, beraz, zerbitzu-izen bera izango dute guztiek.
  • Metodo bati arrastoak gehitzean, begizta batean askotan deitzen ez dela ziurtatu behar duzu. Dei guztietarako arrasto komun bat gehitu behar da, lan-denbora osoa bermatzen duena. Bestela, gehiegizko karga sortuko da.
  • Behin jaeger-ui sartuta, aztarna ugariren eskaera handiegiak egin ziren, eta erantzunaren zain egon ez zirenez, berriro egin zuten. Ondorioz, jaeger-query memoria asko jaten eta elastikoa moteltzen hasi zen. Jaeger-query berrabiaraziz lagunduta

Aztarnak lagintzea, gordetzea eta ikustea

Hiru mota daude laginketa arrastoak:

  1. Aztarna guztiak bidaltzen eta gordetzen dituen Const.
  2. Probabilista, aztarnak probabilitate jakin batekin iragazten dituena.
  3. Ratelimiting horrek segundoko arrasto kopurua mugatzen du. Ezarpen hauek bezeroan konfigura ditzakezu, jaeger-agentean edo biltzailean. Orain const 1 erabiltzen dugu valuator pilan, eskaera asko ez baitaude, baina denbora luzea hartzen dute. Etorkizunean, horrek sisteman gehiegizko karga eragingo badu, muga dezakezu.

Cassandra erabiltzen baduzu, lehenespenez bi egunez bakarrik gordetzen ditu aztarnak. Erabiltzen ari gara elastiko bilaketa eta arrastoak betirako gordetzen dira eta ez dira ezabatzen. Egun bakoitzeko indize bereizia sortzen da, adibidez, jaeger-service-2019-03-04. Etorkizunean, aztarna zaharren garbiketa automatikoa konfiguratu behar duzu.

Aztarnak ikusteko behar duzu:

  • Hautatu aztarnak iragazi nahi dituzun zerbitzua, adibidez, tomcat7-default tomcat-en exekutatzen ari den eta bere izenik izan ezin duen zerbitzu baterako.
  • Ondoren, hautatu eragiketa, denbora-tartea eta gutxieneko eragiketa-denbora, adibidez, 10 segundotik aurrera, exekuzio luzeak soilik hartzeko.
    Service Tracing, OpenTracing eta Jaeger
  • Joan arrastoren batera eta ikusi zer ari zen moteltzen han.
    Service Tracing, OpenTracing eta Jaeger

Gainera, eskaeraren IDren bat ezagutzen bada, ID honen arrastoa aurki dezakezu etiketa-bilaketa baten bidez, ID hau traza-tartean erregistratuta badago.

Dokumentazioa

Artikuluak

Video

Iturria: www.habr.com

Gehitu iruzkin berria