Gjurmimi i Shërbimit, OpenTracing dhe Jaeger

Gjurmimi i Shërbimit, OpenTracing dhe Jaeger

Ne përdorim arkitekturën e mikroshërbimeve në projektet tona. Kur ndodhin pengesa në performancë, harxhohet shumë kohë për monitorimin dhe analizimin e regjistrave. Kur regjistroni kohën e operacioneve individuale në një skedar log, zakonisht është e vështirë të kuptohet se çfarë çoi në thirrjen e këtyre operacioneve, për të gjurmuar sekuencën e veprimeve ose zhvendosjen kohore të një operacioni në lidhje me një tjetër në shërbime të ndryshme.

Për të minimizuar punën manuale, vendosëm të përdorim një nga mjetet e gjurmimit. Rreth asaj se si dhe pse mund të përdorni gjurmimin dhe si e bëmë atë, dhe do të diskutohet në këtë artikull.

Cilat probleme mund të zgjidhen me gjurmim

  1. Gjeni pengesat e performancës si brenda një shërbimi të vetëm ashtu edhe në të gjithë pemën e ekzekutimit midis të gjitha shërbimeve pjesëmarrëse. Për shembull:
    • Shumë thirrje të shkurtra të njëpasnjëshme ndërmjet shërbimeve, për shembull, në gjeokodim ose në një bazë të dhënash.
    • Pritjet e gjata hyrëse/dalëse, të tilla si transferimet në rrjet ose leximet e diskut.
    • Analizimi i gjatë i të dhënave.
    • Operacione të gjata që kërkojnë CPU.
    • Seksione të kodit që nuk nevojiten për të marrë rezultatin përfundimtar dhe mund të hiqen ose vonohen.
  2. Kuptoni qartë se në çfarë sekuence quhet dhe çfarë ndodh kur kryhet operacioni.
    Gjurmimi i Shërbimit, OpenTracing dhe Jaeger
    Mund të shihet se, për shembull, Kërkesa erdhi në shërbimin WS -> shërbimi WS plotësoi të dhënat përmes shërbimit R -> më pas dërgoi një kërkesë në shërbimin V -> shërbimi V ngarkoi shumë të dhëna nga Shërbimi R -> shkoi në shërbimin P -> shërbimi P shkoi përsëri në shërbim R -> shërbimi V injoroi rezultatin dhe shkoi në shërbimin J -> dhe vetëm më pas ktheu përgjigjen në shërbimin WS, ndërsa vazhdon të llogarisë diçka tjetër në sfondin.
    Pa një gjurmë të tillë apo dokumentacion të detajuar për të gjithë procesin, është shumë e vështirë të kuptosh se çfarë po ndodh kur shikon kodin për herë të parë, dhe kodi shpërndahet nëpër shërbime të ndryshme dhe fshihet pas një grupi koshësh dhe ndërfaqesh.
  3. Mbledhja e informacionit në lidhje me pemën e ekzekutimit për analizën e mëvonshme të shtyrë. Në çdo fazë të ekzekutimit, mund të shtoni informacion në gjurmën që është i disponueshëm në këtë fazë dhe më pas të kuptoni se cilat të dhëna hyrëse çuan në një skenar të ngjashëm. Për shembull:
    • ID e përdoruesit
    • Të drejtat
    • Lloji i metodës së zgjedhur
    • Gabim i regjistrit ose ekzekutimit
  4. Kthimi i gjurmëve në një nëngrup metrikash dhe analiza e mëtejshme tashmë në formën e metrikës.

Çfarë gjurme mund të regjistrohet. Hapësirë

Në gjurmim ekziston koncepti i një hapësire, ky është një analog i një regjistri, me tastierën. Spa ka:

  • Emri, zakonisht emri i metodës që u ekzekutua
  • Emri i shërbimit në të cilin u krijua hapësira
  • Vetë ID unike
  • Një lloj meta informacioni në formën e një çelësi/vlere që është regjistruar në të. Për shembull, parametrat e metodës ose metoda përfundoi me një gabim ose jo
  • Koha e fillimit dhe e përfundimit për këtë periudhë
  • ID-ja e hapësirës së prindit

Çdo hapësirë ​​i dërgohet kolektorit të hapësirës për t'u ruajtur në bazën e të dhënave për rishikim të mëvonshëm sapo të ketë përfunduar ekzekutimin e tij. Në të ardhmen, mund të ndërtoni një pemë të të gjitha hapësirave duke u lidhur me ID-në e prindit. Kur analizoni, mund të gjeni, për shembull, të gjitha shtrirjet në një shërbim që zgjati më shumë se pak kohë. Më tej, duke shkuar në një hapësirë ​​specifike, shihni të gjithë pemën sipër dhe poshtë kësaj hapësire.

Gjurmimi i Shërbimit, OpenTracing dhe Jaeger

Opentrace, Jagger dhe si e zbatuam atë për projektet tona

Ekziston një standard i përbashkët gjurmë të hapura, i cili përshkruan se si dhe çfarë duhet të mblidhet, pa u lidhur me një zbatim specifik në asnjë gjuhë. Për shembull, në Java, e gjithë puna me gjurmët kryhet përmes API-së së zakonshme Opentrace, dhe nën të, për shembull, Jaeger ose një zbatim i paracaktuar bosh që nuk bën asgjë mund të fshihet.
Ne jemi duke përdorur Jaeger si një zbatim i Opentrace. Ai përbëhet nga disa komponentë:

Gjurmimi i Shërbimit, OpenTracing dhe Jaeger

  • Jaeger-agent është një agjent lokal që zakonisht instalohet në çdo makinë dhe shërbimet regjistrohen në të në portën e paracaktuar lokale. Nëse nuk ka agjent, atëherë gjurmët e të gjitha shërbimeve në këtë makinë zakonisht çaktivizohen
  • Jaeger-collector - të gjithë agjentët i dërgojnë gjurmët e mbledhura tek ai dhe ai i vendos ato në bazën e të dhënave të zgjedhur
  • Baza e të dhënave është cassandra e tyre e preferuar, por ne përdorim elasticsearch, ka zbatime për disa baza të tjera të dhënash dhe një zbatim në memorie që nuk kursen asgjë në disk
  • Jaeger-query është një shërbim që shkon në bazën e të dhënave dhe kthen gjurmët e mbledhura tashmë për analizë
  • Jaeger-ui është një ndërfaqe në internet për kërkimin dhe shikimin e gjurmëve, shkon te jaeger-query

Gjurmimi i Shërbimit, OpenTracing dhe Jaeger

Një komponent i veçantë mund të quhet zbatimi i opentrace jaeger për gjuhë të veçanta, përmes të cilit spans dërgohen te jaeger-agent.
Lidhja e Jagger në Java zbret në zbatimin e ndërfaqes io.opentracing.Tracer, pas së cilës të gjitha gjurmët përmes saj do të fluturojnë te agjenti real.

Gjurmimi i Shërbimit, OpenTracing dhe Jaeger

Gjithashtu për komponentin e pranverës, mund të lidheni opentracing-pranverë-re-starter dhe zbatimi nga Jaeger opentracing-pranverë-jaeger-cloud-starter i cili automatikisht do të konfigurojë gjurmimin për çdo gjë që kalon përmes këtyre komponentëve, për shembull kërkesat http drejt kontrolluesve, kërkesat për bazën e të dhënave përmes jdbc, etj.

Gjurmët e regjistrimit në Java

Diku në nivelin më të lartë, duhet të krijohet Hapësira e parë, kjo mund të bëhet automatikisht, për shembull, nga kontrolluesi i pranverës kur merret një kërkesë, ose manualisht nëse nuk ka. Më pas transmetohet përmes Fushëveprimit më poshtë. Nëse ndonjë metodë më poshtë dëshiron të shtojë një Hapësirë, ajo merr activeSpan-in aktual nga Scope, krijon një hapësirë ​​të re dhe thotë se prindi i saj është activeSpan-i që rezulton dhe e bën aktiv Hapësirën e re. Kur telefononi shërbime të jashtme, hapësira aktuale aktive u kalon atyre dhe ato shërbime krijojnë hapësira të reja duke iu referuar kësaj hapësirë.
E gjithë puna kalon përmes shembullit Tracer, ju mund ta merrni atë përmes mekanizmit DI, ose GlobalTracer.get () si një ndryshore globale nëse mekanizmi DI nuk funksionon. Si parazgjedhje, nëse gjurmuesi nuk është inicializuar, NoopTracer do të kthehet i cili nuk bën asgjë.
Më tej, shtrirja aktuale merret nga gjurmuesi përmes ScopeManager, krijohet një fushë e re nga ajo aktuale me një lidhje të hapësirës së re, dhe më pas mbyllet Scope e krijuar, e cila mbyll hapësirën e krijuar dhe kthen shtrirjen e mëparshme në gjendjen aktive. Scope është i lidhur me një thread, kështu që kur programoni me shumë fije, nuk duhet të harroni të transferoni hapësirën aktive në një thread tjetër, për aktivizimin e mëtejshëm të Scope të një thread tjetër në lidhje me këtë hapësirë.

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

Për programimin me shumë fije, ekziston gjithashtu TracedExecutorService dhe mbështjellës të ngjashëm që përcjellin automatikisht hapësirën aktuale në thread kur hapen detyrat asinkrone:

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

Për kërkesat e jashtme http ekziston TracingHttpClient

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

Problemet me të cilat u përballëm

  • Fasulet dhe DI nuk funksionojnë gjithmonë nëse gjurmuesi nuk përdoret në një shërbim ose komponent, atëherë Me kabllo automatike Tracer mund të mos funksionojë dhe do t'ju duhet të përdorni GlobalTracer.get().
  • Shënimet nuk funksionojnë nëse nuk është një komponent ose shërbim, ose nëse metoda thirret nga një metodë fqinje e së njëjtës klasë. Duhet të jeni të kujdesshëm për të kontrolluar se çfarë funksionon dhe të përdorni krijimin manual të gjurmëve nëse @Traced nuk funksionon. Ju gjithashtu mund të bashkëngjitni një përpilues shtesë për shënimet java, atëherë ato duhet të funksionojnë kudo.
  • Në çizmet e vjetra të pranverës dhe pranverës, konfigurimi automatik i resë së pranverës së hapur nuk funksionon për shkak të gabimeve në DI, atëherë nëse dëshironi që gjurmët në komponentët e pranverës të funksionojnë automatikisht, mund ta bëni atë në analogji me 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
  • Provoni me burime nuk funksionon në groovy, duhet të përdorni më në fund provoni.
  • Çdo shërbim duhet të ketë emrin e vet Spring.application.në të cilin do të regjistrohen gjurmët. Çfarë bën një emër të veçantë për shitjen dhe testin, në mënyrë që të mos ndërhyjnë me to së bashku.
  • Nëse përdorni GlobalTracer dhe tomcat, atëherë të gjitha shërbimet që funksionojnë në këtë tomcat kanë një GlobalTracer, kështu që të gjitha do të kenë të njëjtin emër shërbimi.
  • Kur shtoni gjurmë në një metodë, duhet të jeni të sigurt që ajo nuk thirret shumë herë në një lak. Është e nevojshme të shtohet një gjurmë e përbashkët për të gjitha thirrjet, e cila garanton kohën totale të punës. Përndryshe, do të krijohet një ngarkesë e tepërt.
  • Pasi në jaeger-ui, u bënë kërkesa shumë të mëdha për një numër të madh gjurmësh dhe meqenëse nuk prisnin përgjigje, e bënë përsëri. Si rezultat, jaeger-query filloi të hante shumë memorie dhe të ngadalësonte elasticitetin. Ndihmuar duke rifilluar jaeger-query

Marrja e mostrave, ruajtja dhe shikimi i gjurmëve

Ka tre lloje gjurmët e kampionimit:

  1. Const që dërgon dhe ruan të gjitha gjurmët.
  2. Probabilistik që filtron gjurmët me një probabilitet të caktuar.
  3. Ratelimiting i cili kufizon numrin e gjurmëve për sekondë. Ju mund t'i konfiguroni këto cilësime në klient, qoftë në agjentin jaeger ose në kolektor. Tani ne përdorim const 1 në raftin e vlerësuesit, pasi nuk ka shumë kërkesa, por ato kërkojnë shumë kohë. Në të ardhmen, nëse kjo do të ushtrojë një ngarkesë të tepërt në sistem, mund ta kufizoni atë.

Nëse përdorni cassandra, atëherë si parazgjedhje ruan gjurmë vetëm për dy ditë. Ne jemi duke përdorur kërkesë elastike dhe gjurmët ruhen gjatë gjithë kohës dhe nuk fshihen. Një indeks i veçantë krijohet për çdo ditë, për shembull jaeger-service-2019-03-04. Në të ardhmen, duhet të konfiguroni pastrimin automatik të gjurmëve të vjetra.

Për të parë gjurmët që ju nevojiten:

  • Zgjidhni shërbimin me të cilin dëshironi të filtroni gjurmët, për shembull, tomcat7-default për një shërbim që funksionon në tomcat dhe nuk mund të ketë emrin e vet.
  • Pastaj zgjidhni operacionin, intervalin kohor dhe kohën minimale të funksionimit, për shembull nga 10 sekonda, për të marrë vetëm ekzekutime të gjata.
    Gjurmimi i Shërbimit, OpenTracing dhe Jaeger
  • Shkoni në një nga gjurmët dhe shikoni se çfarë po ngadalësohej atje.
    Gjurmimi i Shërbimit, OpenTracing dhe Jaeger

Gjithashtu, nëse dihet ndonjë id kërkese, atëherë mund të gjeni një gjurmë nga kjo id përmes një kërkimi të etiketave, nëse kjo id është regjistruar në hapësirën e gjurmës.

Records

Artikuj

Video

Burimi: www.habr.com

Shto një koment