Service Tracing, OpenTracing en Jaeger

Service Tracing, OpenTracing en Jaeger

Ons gebruik mikrodiensargitektuur in ons projekte. Wanneer prestasie-knelpunte voorkom, word baie tyd spandeer om logs te monitor en te ontleed. Wanneer die tydsberekeninge van individuele bewerkings in 'n loglêer aangeteken word, is dit gewoonlik moeilik om te verstaan ​​wat gelei het tot die aanroep van hierdie bewerkings, om die volgorde van aksies of die tydverskuiwing van een bewerking relatief tot 'n ander in verskillende dienste na te spoor.

Om hande-arbeid te verminder, het ons besluit om een ​​van die opsporingsgereedskap te gebruik. Oor hoe en hoekom jy opsporing kan gebruik en hoe ons dit gedoen het, en sal in hierdie artikel bespreek word.

Watter probleme kan met opsporing opgelos word

  1. Vind prestasie-bottelnekke binne 'n enkele diens en in die hele uitvoeringsboom tussen alle deelnemende dienste. Byvoorbeeld:
    • Baie kort opeenvolgende oproepe tussen dienste, byvoorbeeld na geokodering of na 'n databasis.
    • Lang I/O-wagte, soos netwerkoordragte of skyflese.
    • Lang data-ontleding.
    • Lang bedrywighede wat cpu vereis.
    • Gedeeltes van kode wat nie nodig is om die finale resultaat te kry nie en kan verwyder of vertraag word.
  2. Verstaan ​​duidelik in watter volgorde wat genoem word en wat gebeur wanneer die operasie uitgevoer word.
    Service Tracing, OpenTracing en Jaeger
    Dit kan gesien word dat die Versoek byvoorbeeld na die WS-diens gekom het -> die WS-diens het data bygevoeg deur die R-diens -> dan 'n versoek aan die V-diens gestuur -> die V-diens het baie data van die R gelaai diens -> het na die P-diens gegaan -> die P-diens het weer na diens R gegaan -> diens V het die resultaat geïgnoreer en na diens J gegaan -> en dan eers die reaksie na diens WS teruggestuur, terwyl voortgegaan word om iets anders te bereken in die agtergrond.
    Sonder so 'n spoor of gedetailleerde dokumentasie vir die hele proses, is dit baie moeilik om te verstaan ​​wat gebeur as jy vir die eerste keer na die kode kyk, en die kode is oor verskillende dienste versprei en weggesteek agter 'n klomp bakkies en koppelvlakke.
  3. Insameling van inligting oor die uitvoeringsboom vir daaropvolgende uitgestelde analise. In elke stadium van uitvoering kan jy inligting by die spoor voeg wat op hierdie stadium beskikbaar is en dan uitvind watter insetdata tot 'n soortgelyke scenario gelei het. Byvoorbeeld:
    • Gebruikers-ID
    • regte
    • Tipe geselekteerde metode
    • Log of uitvoering fout
  4. Die omskakeling van spore in 'n subset van metrieke en verdere ontleding reeds in die vorm van metrieke.

Watter spoor kan aanteken. Span

In die opsporing is daar die konsep van 'n span, dit is 'n analoog van een log, na die konsole. Die spa het:

  • Naam, gewoonlik die naam van die metode wat uitgevoer is
  • Die naam van die diens waarin die span gegenereer is
  • Eie unieke ID
  • Een of ander meta-inligting in die vorm van 'n sleutel/waarde wat daarby ingeteken is. Byvoorbeeld, metode parameters of die metode het geëindig met 'n fout of nie
  • Begin- en eindtye vir hierdie span
  • Ouerspan-ID

Elke span word na die spanversamelaar gestuur om in die databasis gestoor te word vir latere hersiening sodra dit die uitvoering daarvan voltooi het. In die toekoms kan jy 'n boom van alle streke bou deur met ouer-ID te koppel. Wanneer jy ontleed, kan jy byvoorbeeld al die strekke in een of ander diens vind wat meer as 'n geruime tyd geneem het. Verder, deur na 'n spesifieke span te gaan, sien die hele boom bo en onder hierdie span.

Service Tracing, OpenTracing en Jaeger

Opentrace, Jagger en hoe ons dit vir ons projekte geïmplementeer het

Daar is 'n gemeenskaplike standaard oopspoor, wat beskryf hoe en wat ingesamel moet word, sonder om gekoppel te word aan 'n spesifieke implementering in enige taal. Byvoorbeeld, in Java word alle werk met spore deur die algemene Opentrace API uitgevoer, en daaronder kan byvoorbeeld Jaeger of 'n leë verstekimplementering wat niks doen nie weggesteek word.
Ons gebruik Jaeger as 'n implementering van Opentrace. Dit bestaan ​​uit verskeie komponente:

Service Tracing, OpenTracing en Jaeger

  • Jaeger-agent is 'n plaaslike agent wat gewoonlik op elke masjien geïnstalleer word en dienste word daarby aangemeld op die plaaslike verstekpoort. As daar geen agent is nie, word spore van alle dienste op hierdie masjien gewoonlik gedeaktiveer
  • Jaeger-versamelaar - alle agente stuur versamelde spore na dit, en dit plaas dit in die geselekteerde databasis
  • Die databasis is hul voorkeurkassandra, maar ons gebruik elasticsearch, daar is implementerings vir 'n paar ander databasisse en 'n in-geheue implementering wat niks op skyf stoor nie
  • Jaeger-query is 'n diens wat na die databasis gaan en reeds versamelde spore vir ontleding terugstuur
  • Jaeger-ui is 'n webkoppelvlak om spore te soek en te bekyk, dit gaan na jaeger-navraag

Service Tracing, OpenTracing en Jaeger

'n Afsonderlike komponent kan die implementering van opentrace-jaeger vir spesifieke tale genoem word, waardeur spanne na jaeger-agent gestuur word.
Koppel Jagger in Java kom daarop neer om die io.opentracing.Tracer-koppelvlak te implementeer, waarna alle spore daardeur na die regte agent sal vlieg.

Service Tracing, OpenTracing en Jaeger

Ook vir die veerkomponent kan jy koppel oopspoor-lente-wolk-aansitter en implementering van Jaeger oopspoor-lente-jaeger-wolk-aansitter wat outomaties opsporing sal konfigureer vir alles wat deur hierdie komponente gaan, byvoorbeeld http-versoeke aan beheerders, versoeke na die databasis deur jdbc, ens.

Spoor aanteken in Java

Iewers op die boonste vlak moet die eerste Span geskep word, dit kan outomaties gedoen word, byvoorbeeld deur die veerbeheerder wanneer 'n versoek ontvang word, of handmatig as daar nie een is nie. Dit word dan deur die omvang hieronder versend. As enige metode hieronder 'n Span wil byvoeg, neem dit die huidige activeSpan uit die Scope, skep 'n nuwe Span en sê die ouer daarvan is die resulterende activeSpan, en maak die nuwe Span aktief. Wanneer eksterne dienste gebel word, word die huidige aktiewe span aan hulle deurgegee, en daardie dienste skep nuwe spans met verwysing na hierdie span.
Alle werk gaan deur die Tracer-instansie, jy kan dit deur die DI-meganisme kry, of GlobalTracer.get () as 'n globale veranderlike as die DI-meganisme nie werk nie. By verstek, as tracer nie geïnisialiseer is nie, sal NoopTracer terugkeer wat niks doen nie.
Verder word die huidige omvang verkry vanaf die spoorsnyer deur die ScopeManager, 'n nuwe omvang word geskep vanaf die huidige een met 'n binding van die nuwe span, en dan word die geskepte omvang gesluit, wat die geskepte span sluit en die vorige omvang terugstuur na die aktiewe toestand. Omvang is gekoppel aan 'n draad, dus wanneer multi-draad programmering, moet jy nie vergeet om die aktiewe span oor te dra na 'n ander draad, vir verdere aktivering van die Scope van 'n ander draad met verwysing na hierdie 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)) {
                ...
            }
        });
    }
}

Vir multi-draad programmering is daar ook TracedExecutorService en soortgelyke omhulsels wat die huidige span outomaties na die draad aanstuur wanneer asinchroniese take geloods word:

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

Vir eksterne http-versoeke is daar TracingHttpClient

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

Probleme wat ons in die gesig gestaar het

  • Bone en DI werk nie altyd as die spoorder nie in 'n diens of komponent gebruik word nie Outobedraad Tracer mag dalk nie werk nie en jy sal GlobalTracer.get() moet gebruik.
  • Aantekeninge werk nie as dit nie 'n komponent of diens is nie, of as die metode vanaf 'n naburige metode van dieselfde klas geroep word. Jy moet versigtig wees om te kyk wat werk en handmatige spoorskepping gebruik as @Traced nie werk nie. Jy kan ook 'n bykomende samesteller vir Java-aantekeninge aanheg, dan behoort hulle oral te werk.
  • In die ou veer- en veerstewel werk die ooptrekveerwolk-outokonfigurasie nie as gevolg van foute in DI nie, dan as jy wil hê dat die spore in die veerkomponente outomaties moet werk, kan jy dit na analogie van 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
  • Probeer met hulpbronne werk nie in groovy nie, jy moet probeer uiteindelik gebruik.
  • Elke diens moet sy eie spring.application.name hê waaronder spore aangeteken sal word. Wat beteken 'n aparte naam vir die verkoop en die toets, sodat dit nie inmeng met hulle saam.
  • As jy GlobalTracer en tomcat gebruik, dan het alle dienste wat in hierdie tomcat loop een GlobalTracer, so hulle sal almal dieselfde diensnaam hê.
  • Wanneer jy spore by 'n metode voeg, moet jy seker wees dat dit nie baie keer in 'n lus genoem word nie. Dit is nodig om een ​​gemeenskaplike spoor vir alle oproepe by te voeg, wat die totale werktyd waarborg. Andersins sal 'n oortollige vrag geskep word.
  • Een keer in jaeger-ui is te groot versoeke vir 'n groot aantal spore gerig, en aangesien hulle nie vir 'n reaksie gewag het nie, het hulle dit weer gedoen. As gevolg hiervan het jaeger-query baie geheue begin eet en elasties vertraag. Gehelp deur jaeger-query weer te begin

Monsterneming, berging en besigtiging van spore

Daar is drie tipes steekproefspore:

  1. Const wat alle spore stuur en stoor.
  2. Waarskynlik wat spore met een of ander gegewe waarskynlikheid filter.
  3. Ratelimiting wat die aantal spore per sekonde beperk. U kan hierdie instellings op die kliënt instel, hetsy op die jaeger-agent of op die versamelaar. Nou gebruik ons ​​konst 1 in die waardeerderstapel, aangesien daar nie baie versoeke is nie, maar dit neem lank. In die toekoms, as dit 'n oormatige las op die stelsel sal uitoefen, kan u dit beperk.

As jy Cassandra gebruik, stoor dit by verstek net spore vir twee dae. Ons gebruik elasticsearch en spore word vir alle tye gestoor en word nie uitgevee nie. 'n Aparte indeks word vir elke dag geskep, byvoorbeeld jaeger-service-2019-03-04. In die toekoms moet u outomatiese skoonmaak van ou spore instel.

Om die spore te sien benodig jy:

  • Kies die diens waarmee jy spore wil filter, byvoorbeeld tomcat7-verstek vir 'n diens wat in die tomcat loop en nie sy eie naam kan hê nie.
  • Kies dan die bewerking, die tydinterval en die minimum bewerkingstyd, byvoorbeeld vanaf 10 sekondes, om net lang uitvoerings te neem.
    Service Tracing, OpenTracing en Jaeger
  • Gaan na een van die spore en kyk wat vertraag daar.
    Service Tracing, OpenTracing en Jaeger

Ook, as 'n versoek-ID bekend is, dan kan jy 'n spoor deur hierdie id vind deur 'n merkersoektog, as hierdie id in die spoorspan aangeteken is.

Dokumentasie

Artikels

video

Bron: will.com

Voeg 'n opmerking