Service Tracing, OpenTracing a Jaeger

Service Tracing, OpenTracing a Jaeger

An eise Projete benotze mir Microservice Architektur. Wann d'Leeschtungsfäegkeeten optrieden, gëtt vill Zäit un Iwwerwaachung an Parsing vu Logbicher verbruecht. Wann Dir d'Timings vun eenzel Operatiounen an eng Logdatei protokolléiert, ass et normalerweis schwéier ze verstoen wat zu der Uruff vun dësen Operatiounen gefouert huet, d'Sequenz vun Aktiounen oder d'Zäitverschiebung vun enger Operatioun relativ zu enger anerer a verschiddene Servicer ze verfolgen.

Fir manuell Aarbecht ze minimiséieren, hu mir beschloss ee vun den Tracing-Tools ze benotzen. Wéi a fir wat Dir Tracing benotze kënnt a wéi mir et gemaach hunn, gëtt an dësem Artikel diskutéiert.

Wéi eng Problemer kënne mat Tracing geléist ginn?

  1. Fannt Leeschtungsfäegkeeten souwuel bannent engem eenzegen Service an iwwer de ganzen Ausféierungsbaum tëscht all deelhuelende Servicer. Zum Beispill:
    • Vill kuerz sequenziell Uruff tëscht Servicer, zum Beispill op Geokodéierung oder op eng Datebank.
    • Laang I/O Waart, sou wéi d'Transfert vun Daten iwwer e Netzwierk oder d'Liesen vun der Disk.
    • Laang Daten Parsing.
    • Laang Operatiounen déi CPU erfuerderen.
    • Sektioune vum Code déi net gebraucht ginn fir d'Finale Resultat ze kréien a kënne geläscht oder ausgesat ginn.
  2. Verstinn kloer a wéi enger Reiefolleg wat genannt gëtt a wat geschitt wann d'Operatioun duerchgefouert gëtt.
    Service Tracing, OpenTracing a Jaeger
    Et kann gesi ginn, datt zum Beispill d'Ufro un de WS-Service komm ass -> de WS-Service huet d'Donnéeën iwwer de R-Service ergänzt -> dann d'Ufro un de V-Service geschéckt -> de V-Service huet vill Daten aus der R Service -> op de Service P gaangen -> de Service P ass erëm an de Service R -> Service V huet d'Resultat ignoréiert an ass op de Service J gaang -> an eréischt duerno d'Äntwert op de Service WS zréckginn, wärend nach eppes anescht ausrechnen an den Hannergrond.
    Ouni sou eng Spuer oder detailléiert Dokumentatioun fir de ganze Prozess ass et ganz schwéier ze verstoen wat geschitt nodeems Dir de Code fir d'éischte Kéier kuckt, an de Code ass iwwer verschidde Servicer verspreet a verstoppt hannert enger Rëtsch Bounen an Interfaces.
  3. Sammlung vun Informatioun iwwer den Ausféierungsbaum fir spéider ofgeschloss Analyse. Op all Etapp vun der Ausféierung kënnt Dir d'Informatioun, déi op dëser Etapp verfügbar ass, op d'Spuer addéieren an dann erausfannen wéi eng Inputdaten zu sou engem Szenario gefouert hunn. Zum Beispill:
    • Benotzer ID
    • Rechter
    • Typ vun Method ausgewielt
    • Log oder Ausféierung Feeler
  4. Spueren an eng Ënnergrupp vu Metriken ëmsetzen a weider Analyse a Form vu Metriken.

Wat Tracing kann aloggen. Spann

Am Tracing gëtt et d'Konzept vu Spann, dëst ass en Analog vun engem Logbuch op d'Konsol. Spann huet:

  • Numm, normalerweis den Numm vun der Method déi ausgefouert gouf
  • Numm vum Service wou d'Spann generéiert gouf
  • Eegent eenzegaarteg ID
  • E puer Meta-Informatiounen a Form vu Schlëssel / Wäert, déi dran abegraff war. Zum Beispill Method Parameteren oder ob d'Method mat engem Feeler opgehalen huet oder net
  • D'Start- an Ennzäite vun dëser Spannausféierung
  • Elterenspan ID

All Spann gëtt un de Spannsammler geschéckt fir an der Datebank gespäichert ze ginn fir spéider ze kucken soubal et seng Ausféierung ofgeschloss huet. An der Zukunft kënnt Dir e Bam vun all Spann bauen andeems Dir se mat Elteren-ID verbënnt. Wann Dir analyséiert, kënnt Dir zum Beispill all Spann an engem Service fannen, dee méi wéi eng Zäit gedauert huet. Da gitt op eng spezifesch Spann, kuckt de ganze Bam uewen an ënner dëser Spann.

Service Tracing, OpenTracing a Jaeger

Opentrace, Jagger a wéi mir et fir eis Projeten ëmgesat hunn

Et gëtt e gemeinsame Standard Opentrace, déi beschreift wéi a wat soll gesammelt ginn, ouni duerch Spuer un eng spezifesch Ëmsetzung an enger Sprooch gebonnen ze sinn. Zum Beispill, am Java, gëtt all Aarbecht mat Spuren duerch déi gemeinsam Opentrace API duerchgefouert, an ënner kann et verstoppt ginn, zum Beispill Jaeger oder eng eidel Standardimplementatioun déi näischt mécht.
Mir benotzen Jaeger als Ëmsetzung vun Opentrace. Et besteet aus e puer Komponenten:

Service Tracing, OpenTracing a Jaeger

  • Jaeger-Agent ass e lokalen Agent deen normalerweis op all Maschinn installéiert ass a Servicer sinn op de lokalen Standardport ageloggt. Wann et keen Agent ass, sinn d'Spure vun all Servicer op dëser Maschinn normalerweis ausgeschalt
  • Jaeger-Sammler - all Agenten schécken gesammelt Spuren op et, an et setzt se an déi gewielte Datebank
  • Datebank - hir léifste ass Cassandra, awer mir benotzen elasticsearch, et gi Implementatioune fir e puer aner Datenbanken an eng In-Memory Implementatioun déi näischt op Disk späichert
  • Jaeger-Query ass e Service deen an d'Datebank geet a scho gesammelt Spure fir Analyse liwwert
  • Jaeger-ui ass e Webinterface fir Spuren ze sichen an ze kucken, et leeft a jaeger-query

Service Tracing, OpenTracing a Jaeger

Eng separat Komponent kann eng Opentrace Jaeger Implementatioun fir spezifesch Sproochen genannt ginn, duerch déi Spannungen op jaeger-Agent geschéckt ginn.
Jagger an Java verbannen kënnt erof op d'Ëmsetzung vun der io.opentracing.Tracer Interface, no deem all Spuren duerch et zu der real Agent fléien.

Service Tracing, OpenTracing a Jaeger

Dir kënnt och Fréijoer Komponente verbannen opentracing-Fréijoer-Cloud-Starter an Ëmsetzung vum Jaeger opentracing-spring-jaeger-cloud-starter déi automatesch Tracing konfiguréieren fir alles wat duerch dës Komponenten passéiert, zum Beispill http Ufroen un Controller, Ufroen un d'Datebank iwwer jdbc, etc.

Logged Spuren am Java

Iergendwou um Top-Niveau muss den éischte Span erstallt ginn, dëst kann automatesch gemaach ginn, zum Beispill vum Fréijoerskontroller wann Dir eng Ufro kritt, oder manuell wann et keng gëtt. Et gëtt dann iwwer Scope ënnen iwwerdroen. Wann eng Method hei ënnen e Span addéiere wëllt, hëlt se den aktuellen ActiveSpan vum Scope, erstellt en neie Span a seet datt säin Elterendeel activeSpan krut, a mécht déi nei Span aktiv. Wann extern Servicer opgeruff ginn, gëtt déi aktuell aktiv Spann hinnen iwwerginn, an dës Servicer kreéieren nei Spann, déi mat dëser Spann verbonne sinn.
All Aarbecht geet duerch d'Tracer Instanz; Dir kënnt et duerch den DI Mechanismus kréien, oder GlobalTracer.get() als eng global Variabel wann den DI Mechanismus net funktionnéiert. Par défaut, wann de Tracer net initialiséiert gouf, gëtt NoopTracer zréckginn wat näischt mécht.
Als nächst gëtt den aktuellen Ëmfang vum Tracer iwwer ScopeManager kritt, en neien Ëmfang gëtt aus dem aktuellen erstallt mat enger neier Spann befestegt, an dann ass de erstallte Scope zou, wat de geschafene Spann zoumaacht an de fréiere Scope an den aktiven Zoustand zréckkënnt. . Ëmfang ass un e Fuedem gebonnen, also wann Dir Multi-Threaded Programméiere musst Dir drun erënneren déi aktiv Spann op en anere Fuedem ze transferéieren, fir weider Aktivatioun vum Ëmfang vun engem anere Fuedem un dës Spann gebonnen.

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

Fir Multi-threaded Programméierung gëtt et och TracedExecutorService an ähnlech Wrapper déi automatesch déi aktuell Spann op de Fuedem weiderginn wann se asynchron Aufgaben lafen:

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

Fir extern http Ufroe gëtt et TracingHttpClient

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

Problemer hu mir konfrontéiert

  • Bounen an DI funktionnéieren net ëmmer wann de Tracer net an engem Service oder Komponent benotzt gëtt, dann Autowired Tracer funktionnéiert vläicht net an Dir musst GlobalTracer.get benotzen ().
  • Annotatiounen funktionnéieren net wann et net e Komponent oder Service ass, oder wann de Methodruff aus enger Nopeschmethod vun der selwechter Klass kënnt. Dir musst virsiichteg sinn, iwwerpréift wat funktionnéiert, a benotzt manuell Spuerkreatioun wann @Traced net funktionnéiert. Dir kënnt och en zousätzleche Compiler fir Java Annotatiounen befestegt, da sollt et iwwerall funktionnéieren.
  • Am alen Fréijoer a Fréijoersboot funktionnéiert d'Opentraing Fréijoerswollek Autokonfiguratioun net wéinst Bugs am DI, dann wann Dir Spueren am Fréijoerskomponenten automatesch wëllt funktionnéieren, kënnt Dir et duerch Analogie maachen 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
  • Probéiert mat Ressourcen funktionnéiert net a Groovy; Dir musst probéieren endlech ze benotzen.
  • All Service muss seng eege spring.application.name hunn, ënner deenen d'Spure protokolléiert ginn. Wéi wier et mat engem separaten Numm fir Verkaf an Tester, fir se net mateneen ze vermëschen.
  • Wann Dir GlobalTracer an Tomcat benotzt, dann hunn all Servicer, déi an dësem Tomcat lafen, een GlobalTracer, sou datt se all dee selwechte Servicenumm hunn.
  • Wann Dir Spure fir eng Method bäidréit, musst Dir sécher sinn datt et net vill Mol an enger Loop genannt gëtt. Dir musst eng gemeinsam Spuer fir all Uruff addéieren, déi d'total Operatiounszäit ophuelen. Soss gëtt iwwerschësseg Laascht erstallt.
  • Eemol am jaeger-ui hunn se ze grouss Ufroe fir eng grouss Zuel vu Spuren gemaach a well se net op eng Äntwert gewaart hunn, hunn se et nach eng Kéier gemaach. Als Resultat hunn d'Jaeger-Query ugefaang vill Erënnerung ze iessen an elastesch ze luesen. Hëlleft duerch Neistart Jaeger-Query

Proben, späicheren a kucken Spuren

Et ginn dräi Zorte Spuerproben:

  1. Const déi all Spure schéckt a späichert.
  2. Probabilistesch déi Spure mat enger gewësser Wahrscheinlechkeet filtert.
  3. Ratemiting déi d'Zuel vun de Spuren pro Sekonn limitéiert. Dir kënnt dës Astellungen um Client konfiguréieren, entweder op jaeger-Agent oder um Sammler. Elo benotze mir const 1 am Bewäertungsstack well et net ganz vill Ufroe sinn, awer se daueren laang. An Zukunft, wann dëst eng onnéideg Laascht op de System setzt, kënnt Dir et limitéieren.

Wann Dir Cassandra benotzt, späichert se Par défaut nëmmen Spueren fir zwee Deeg. Mir benotzen elastesch Sich a Spure gi fir déi ganz Zäit gespäichert a ginn net geläscht. En separaten Index gëtt fir all Dag erstallt, zum Beispill jaeger-service-2019-03-04. An Zukunft musst Dir automatesch Botzen vun alen Spuren konfiguréieren.

Fir d'Spure ze gesinn, musst Dir:

  • Wielt de Service duerch deen Dir Spure filtere wëllt, zum Beispill tomcat7-Standard fir e Service deen am Tomcat leeft an net säin eegenen Numm kann hunn.
  • Wielt dann d'Operatioun, d'Zäitperiod an d'Mindestbetribszäit, zum Beispill vun 10 Sekonnen, fir nëmme laang Ausféierungen ze huelen.
    Service Tracing, OpenTracing a Jaeger
  • Gitt op eng vun de Spuren a kuckt wat do verlangsamt gouf.
    Service Tracing, OpenTracing a Jaeger

Och, wann e puer Ufro ID bekannt ass, da kënnt Dir eng Spuer duerch dës ID duerch eng Tag Sich fannen, wann dës ID an der Spuer vun der Spuer ageloggt ass.

Dokumentatioun

Artikelen

Видео

Source: will.com

Setzt e Commentaire