Service Tracing, OpenTracing en Jaeger

Service Tracing, OpenTracing en Jaeger

Wy brûke microservice-arsjitektuer yn ús projekten. As knelpunten yn prestaasjes foarkomme, wurdt in protte tiid bestege oan it kontrolearjen en parsearjen fan logs. By it ynlogjen fan de timings fan yndividuele operaasjes nei in lochbestân, is it meastentiids lestich te begripen wat late ta it oproppen fan dizze operaasjes, om de folchoarder fan aksjes of de tiidferskowing fan ien operaasje relatyf oan in oare yn ferskate tsjinsten te folgjen.

Om hânwurk te minimalisearjen, hawwe wy besletten ien fan 'e tracing-ark te brûken. Oer hoe en wêrom kinne jo tracing brûke en hoe't wy it dien hawwe, en sil wurde besprutsen yn dit artikel.

Hokker problemen kinne wurde oplost mei tracing

  1. Fyn prestaasjeknelpunten sawol binnen ien tsjinst as yn 'e folsleine útfieringsbeam tusken alle dielnimmende tsjinsten. Bygelyks:
    • In protte koarte opienfolgjende petearen tusken tsjinsten, bygelyks nei geokodearjen of nei in databank.
    • Lange I/O-wachten, lykas netwurkferfier of disk-lêzen.
    • Lange gegevensparsing.
    • Lange operaasjes dy't cpu fereaskje.
    • Seksjes fan koade dy't net nedich binne om it definitive resultaat te krijen en kinne wurde fuortsmiten of fertrage.
  2. Dúdlik begryp yn hokker folchoarder wat hjit en wat bart as de operaasje wurdt útfierd.
    Service Tracing, OpenTracing en Jaeger
    It kin sjoen wurde dat bygelyks it Fersyk by de WS-tsjinst kaam -> de WS-tsjinst de gegevens oanfolle troch de R-tsjinst -> dêrnei in fersyk nei de V-tsjinst stjoerd -> de V-tsjinst laadde in soad gegevens fan de R-tsjinst -> gie nei de P-tsjinst -> de P-tsjinst gie wer nei tsjinst R -> tsjinst V negearre it resultaat en gie nei tsjinst J -> en joech pas dan it antwurd werom nei tsjinst WS, wylst trochgie mei it berekkenjen fan wat oars yn de eftergrûn.
    Sûnder sa'n spoar of detaillearre dokumintaasje foar it hiele proses, it is hiel lestich om te begripen wat der bart as jo sjogge op de koade foar de earste kear, en de koade is ferspraat oer ferskate tsjinsten en ferburgen efter in boskje bins en ynterfaces.
  3. Samling fan ynformaasje oer de útfieringsbeam foar folgjende útstelde analyse. Op elke poadium fan útfiering kinne jo ynformaasje tafoegje oan it spoar dat op dit poadium beskikber is en dan útfine hokker ynfiergegevens liede ta in ferlykber senario. Bygelyks:
    • Brûker ID
    • Rjochten
    • Soart selektearre metoade
    • Log- of útfieringsflater
  4. Spoaren omsette yn in subset fan metriken en fierdere analyze al yn 'e foarm fan metriken.

Wat spoar kin log. Span

By tracing is d'r it konsept fan in span, dit is in analoog fan ien log, nei de konsole. De spa hat:

  • Namme, meastal de namme fan 'e metoade dy't útfierd is
  • De namme fan de tsjinst wêryn de span waard oanmakke
  • Eigen unike ID
  • Guon meta-ynformaasje yn 'e foarm fan in kaai / wearde dy't dêr ynlogd is. Bygelyks, metoade parameters of de metoade einige mei in flater of net
  • Begjin- en eintiden foar dizze span
  • Parent span ID

Elts span wurdt stjoerd nei de span samler te wurde opslein yn de databank foar letter resinsje sa gau as it hat foltôge syn útfiering. Yn 'e takomst kinne jo in beam bouwe fan alle spanen troch te ferbinen troch âlder id. By it analysearjen kinne jo bygelyks alle oerspann yn guon tsjinst fine dy't mear as wat tiid namen. Fierder, troch nei in spesifike span te gean, sjoch de hiele beam boppe en ûnder dizze span.

Service Tracing, OpenTracing en Jaeger

Opentrace, Jagger en hoe't wy it ymplementearre hawwe foar ús projekten

Der is in mienskiplike standert iepentrace, dy't beskriuwt hoe en wat ynsammele wurde moat, sûnder dat se bûn wurde troch tracing oan in spesifike ymplemintaasje yn hokker taal dan ek. Bygelyks, yn Java, alle wurk mei spoaren wurdt útfierd troch de mienskiplike Opentrace API, en ûnder it, bygelyks, Jaeger of in lege standert ymplemintaasje dat docht neat kin wurde ferburgen.
Wy brûke Jager as ymplemintaasje fan Opentrace. It bestiet út ferskate komponinten:

Service Tracing, OpenTracing en Jaeger

  • Jaeger-agent is in lokale agint dy't normaal is ynstalleare op elke masine en tsjinsten wurde oanmeld op 'e lokale standertpoarte. As d'r gjin agent is, dan binne spoaren fan alle tsjinsten op dizze masine normaal útskeakele
  • Jaeger-samler - alle aginten stjoere sammele spoaren nei it, en it set se yn 'e selekteare databank
  • De databank is har foarkar Cassandra, mar wy brûke elasticsearch, d'r binne ymplemintaasjes foar in pear oare databases en in ymplemintaasje yn it ûnthâld dy't neat opslaat op skiif
  • Jaeger-query is in tsjinst dy't nei de databank giet en al sammele spoaren werombringt foar analyse
  • Jaeger-ui is in webynterface foar it sykjen en besjen fan spoaren, it giet nei jaeger-query

Service Tracing, OpenTracing en Jaeger

In aparte komponint kin neamd wurde de ymplemintaasje fan opentrace jaeger foar spesifike talen, troch hokker spans wurde stjoerd nei jaeger-agent.
Jagger ferbine yn Java komt del op it útfieren fan de io.opentracing.Tracer ynterface, wêrnei't alle spoaren dêrtroch fleane nei de echte agint.

Service Tracing, OpenTracing en Jaeger

Ek foar de spring komponint, kinne jo ferbine opentracing-spring-wolk-starter en ymplemintaasje fan Jaeger opentracing-spring-jaeger-cloud-starter dy't automatysk tracing sil konfigurearje foar alles dat troch dizze komponinten giet, bygelyks http-oanfragen oan controllers, fersiken nei de databank fia jdbc, ensfh.

Traces oanmelden yn Java

Earne op it boppeste nivo moat de earste Span oanmakke wurde, dit kin automatysk dien wurde, bygelyks troch de springcontroller as in fersyk ûntfongen is, of mei de hân as der gjin is. It wurdt dan oerdroegen fia de Scope hjirûnder. As ien fan 'e metoade hjirûnder in Span taheakje wol, nimt de hjoeddeistige aktiveSpan út' e Scope, makket in nije Span en seit dat syn âlder de resultearjende aktiveSpan is, en makket de nije Span aktyf. By it roppen fan eksterne tsjinsten wurdt de hjoeddeistige aktive span oan har trochjûn, en dy tsjinsten meitsje nije spans mei ferwizing nei dizze span.
Alle wurk giet troch de Tracer-eksimplaar, jo kinne it krije fia it DI-meganisme, of GlobalTracer.get () as in globale fariabele as it DI-meganisme net wurket. Standert, as tracer net inisjalisearre is, sil NoopTracer weromkomme dy't neat docht.
Fierder wurdt de aktuele scope krigen fan 'e tracer fia de ScopeManager, in nije scope wurdt makke fan 'e hjoeddeiske mei in bining fan 'e nije span, en dan wurdt de oanmakke Scope sluten, dy't de oanmakke span slút en de foarige Scope werombringt nei de aktive steat. Scope is bûn oan in tried, dus doe't multi-threaded programmearring, Jo moatte net ferjitte te oerdrage de aktive span nei in oare tried, foar fierdere aktivearring fan de Scope fan in oare tried mei ferwizing nei dizze 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)) {
                ...
            }
        });
    }
}

Foar multi-threaded programmearring is d'r ek TracedExecutorService en ferlykbere wrappers dy't de hjoeddeistige span automatysk trochstjoere nei de thread as asynchrone taken wurde lansearre:

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

Foar eksterne http-oanfragen is d'r TracingHttpClient

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

Problemen dy't wy konfrontearre

  • Beanen en DI net altyd wurkje as de tracer wurdt net brûkt yn in tsjinst of komponint, dan Autowired Tracer kin net wurkje en jo moatte GlobalTracer.get() brûke.
  • Annotaasjes wurkje net as it gjin komponint of tsjinst is, of as de metoade wurdt oanroppen fan in oanbuorjende metoade fan deselde klasse. Jo moatte foarsichtich wêze om te kontrolearjen wat wurket en manuele spoar oanmeitsje as @Traced net wurket. Jo kinne ek in ekstra gearstaller taheakje foar java-annotaasjes, dan moatte se oeral wurkje.
  • Yn 'e âlde maitiid en spring boot wurket de iepentraing springwolk autokonfiguraasje net fanwege bugs yn DI, dan as jo wolle dat de spoaren yn' e maitiidskomponinten automatysk wurkje, kinne jo it dwaan troch analogy mei 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
  • Besykje mei boarnen wurket net yn groovy, jo moatte einlings besykje.
  • Elke tsjinst moat in eigen spring.application.name hawwe wêrop spoaren wurde oanmeld. Wat docht in aparte namme foar de ferkeap en de test, om net te bemuoie mei harren tegearre.
  • As jo ​​​​GlobalTracer en tomcat brûke, dan hawwe alle tsjinsten dy't yn dizze tomcat rinne, ien GlobalTracer, sadat se allegear deselde tsjinstnamme hawwe.
  • By it tafoegjen fan spoaren oan in metoade, moatte jo der wis fan wêze dat it net in protte kearen yn in loop neamd wurdt. It is nedich om ien mienskiplike spoar ta te foegjen foar alle oproppen, dy't de totale wurktiid garandearret. Oars, in oerstallige lading wurdt oanmakke.
  • Ien kear yn jaeger-ui waarden te grutte oanfragen dien foar in grut oantal spoaren, en om't se net wachtsje op in antwurd, diene se it nochris. As gefolch, jaeger-query begûn te iten in soad ûnthâld en fertrage elastysk. Holpen troch it opnij starte fan jaeger-query

Sampling, opslaan en besjen fan spoaren

Der binne trije soarten sampling spoaren:

  1. Const dy't stjoert en bewarret alle spoaren.
  2. Probabilistysk dy't spoaren filteret mei guon opjûne kâns.
  3. Ratelimiting dy't it oantal spoaren per sekonde beheint. Jo kinne dizze ynstellingen konfigurearje op 'e kliïnt, itsij op' e jaeger-agent as op 'e samler. No brûke wy const 1 yn 'e evaluatorstapel, om't d'r net folle oanfragen binne, mar se duorje lang. Yn 'e takomst, as dit in oerstallige lading op it systeem sil oefenje, kinne jo it beheine.

As jo ​​​​cassandra brûke, dan bewarret it standert allinich spoaren foar twa dagen. Wy brûke elastyk sykje en spoaren wurde opslein foar altyd en wurde net wiske. In aparte yndeks wurdt makke foar elke dei, bygelyks jaeger-service-2019-03-04. Yn 'e takomst moatte jo automatyske reiniging fan âlde spoaren ynstelle.

Om de spoaren te besjen hawwe jo nedich:

  • Selektearje de tsjinst wêrmei jo spoaren filterje wolle, bygelyks tomcat7-standert foar in tsjinst dy't rint yn 'e tomcat en kin gjin eigen namme hawwe.
  • Selektearje dan de operaasje, it tiidynterval en de minimale operaasjetiid, bygelyks fan 10 sekonden, om allinich lange útfieringen te nimmen.
    Service Tracing, OpenTracing en Jaeger
  • Gean nei ien fan de spoaren en sjoch wat der fertrage.
    Service Tracing, OpenTracing en Jaeger

Ek, as guon fersyk-id bekend is, dan kinne jo in spoar fine troch dizze id troch in tag-sykjen, as dizze id ynlogd is yn 'e spoarspan.

Dokumintaasje

artikels

Видео

Boarne: www.habr.com

Add a comment