Sledovanie služieb, OpenTracing a Jaeger

Sledovanie služieb, OpenTracing a Jaeger

V našich projektoch využívame mikroservisnú architektúru. Keď dôjde k prekážkam výkonu, veľa času sa strávi monitorovaním a analýzou protokolov. Pri protokolovaní časovania jednotlivých operácií do log súboru je zvyčajne ťažké pochopiť, čo viedlo k vyvolaniu týchto operácií, sledovať postupnosť akcií alebo časový posun jednej operácie voči druhej v rôznych službách.

Aby sme minimalizovali ručnú prácu, rozhodli sme sa použiť jeden z nástrojov na sledovanie. O tom, ako a prečo môžete použiť sledovanie a ako sme to urobili, sa bude diskutovať v tomto článku.

Aké problémy je možné vyriešiť sledovaním

  1. Nájdite prekážku výkonu v rámci jednej služby aj v celom vykonávacom strome medzi všetkými zúčastnenými službami. Napríklad:
    • Mnoho krátkych po sebe idúcich hovorov medzi službami, napríklad do geokódovania alebo do databázy.
    • Dlhé I/O čakania, ako sú sieťové prenosy alebo čítanie disku.
    • Dlhá analýza údajov.
    • Dlhé operácie vyžadujúce CPU.
    • Časti kódu, ktoré nie sú potrebné na získanie konečného výsledku a môžu byť odstránené alebo oneskorené.
  2. Jasne pochopte, v akom poradí sa volá a čo sa stane, keď sa operácia vykoná.
    Sledovanie služieb, OpenTracing a Jaeger
    Je vidieť, že napríklad prišla Požiadavka na službu WS -> služba WS doplnila údaje cez službu R -> potom poslala požiadavku na službu V -> služba V načítala veľa údajov zo služby. Služba R -> prešla do služby P -> služba P prešla znova do služby R -> služba V ignorovala výsledok a prešla do služby J -> a až potom vrátila odpoveď službe WS, pričom pokračovala vo výpočte niečoho iného v pozadie.
    Bez takejto stopy alebo podrobnej dokumentácie k celému procesu je veľmi ťažké pochopiť, čo sa deje pri prvom pohľade na kód a kód je roztrúsený po rôznych službách a skrytý za kopou košov a rozhraní.
  3. Zhromažďovanie informácií o strome vykonávania pre následnú odloženú analýzu. V každej fáze vykonávania môžete do sledovania pridať informácie, ktoré sú v tejto fáze dostupné, a potom zistiť, aké vstupné údaje viedli k podobnému scenáru. Napríklad:
    • ID používateľa
    • práva
    • Typ zvolenej metódy
    • Chyba protokolu alebo vykonania
  4. Premena stôp na podmnožinu metrík a ďalšia analýza už vo forme metrík.

Aká stopa môže zaznamenať. Span

Pri sledovaní existuje koncept rozpätia, je to analóg jedného denníka ku konzole. Kúpele majú:

  • Názov, zvyčajne názov metódy, ktorá bola vykonaná
  • Názov služby, v ktorej bol vygenerovaný rozsah
  • Vlastné jedinečné ID
  • Nejaký druh meta informácií vo forme kľúča/hodnoty, ktorý bol doň prihlásený. Napríklad parametre metódy alebo metóda skončila s chybou alebo nie
  • Časy začiatku a konca pre toto obdobie
  • ID rodičovského rozsahu

Každý rozsah je odoslaný do zberača rozsahov, aby bol uložený v databáze na neskoršie preskúmanie, hneď ako dokončí svoju realizáciu. V budúcnosti môžete vytvoriť strom všetkých rozsahov pripojením podľa ID rodiča. Pri analýze môžete nájsť napríklad všetky rozpätia v niektorej službe, ktorá trvala viac ako nejaký čas. Ďalej, keď prejdete na konkrétne rozpätie, uvidíte celý strom nad a pod týmto rozpätím.

Sledovanie služieb, OpenTracing a Jaeger

Opentrace, Jagger a ako sme to implementovali do našich projektov

Existuje spoločný štandard opentrace, ktorý popisuje, ako a čo by sa malo zhromažďovať, bez toho, aby bol viazaný sledovaním konkrétnej implementácie v akomkoľvek jazyku. Napríklad v Jave sa všetka práca so stopami vykonáva cez bežné API Opentrace a pod ním sa dá skryť napríklad Jaeger alebo prázdna predvolená implementácia, ktorá nič nerobí.
Používame Morský vták ako implementácia Opentrace. Skladá sa z niekoľkých komponentov:

Sledovanie služieb, OpenTracing a Jaeger

  • Jaeger-agent je lokálny agent, ktorý je zvyčajne nainštalovaný na každom počítači a služby sú doň prihlásené na lokálnom predvolenom porte. Ak neexistuje žiadny agent, stopy všetkých služieb na tomto počítači sú zvyčajne zakázané
  • Jaeger-collector - všetci agenti mu posielajú zozbierané stopy a on ich vloží do vybranej databázy
  • Databáza je ich preferovaná cassandra, ale používame elasticsearch, existujú implementácie pre niekoľko ďalších databáz a implementácia v pamäti, ktorá neukladá nič na disk
  • Jaeger-query je služba, ktorá ide do databázy a vracia už zozbierané stopy na analýzu
  • Jaeger-ui je webové rozhranie na vyhľadávanie a prezeranie stôp, ide do jaeger-query

Sledovanie služieb, OpenTracing a Jaeger

Samostatným komponentom možno nazvať implementáciu opentrace jaeger pre špecifické jazyky, prostredníctvom ktorej sú rozpätia odosielané jaeger-agentovi.
Pripojenie Jaggera v Jave prichádza na implementáciu rozhrania io.openracing.Tracer, po ktorom všetky stopy cez neho preletia k skutočnému agentovi.

Sledovanie služieb, OpenTracing a Jaeger

Tiež pre pružinový komponent môžete pripojiť opentracing-jar-cloud-starter a implementácia od spoločnosti Jaeger opentracing-spring-jaeger-cloud-starter ktorý automaticky nakonfiguruje sledovanie všetkého, čo prechádza cez tieto komponenty, napríklad http požiadavky na radiče, požiadavky do databázy cez jdbc atď.

Sleduje protokolovanie v Jave

Niekde na najvyššej úrovni musí byť vytvorené prvé rozpätie, to sa dá urobiť automaticky, napríklad pružinovým ovládačom pri prijatí požiadavky, alebo manuálne, ak žiadna neexistuje. Potom sa prenáša prostredníctvom nižšie uvedeného rozsahu. Ak niektorá z nižšie uvedených metód chce pridať rozsah, zoberie aktuálne aktívne rozpätie z rozsahu, vytvorí nové rozpätie a povie, že jeho rodičom je výsledné aktívne rozpätie, a urobí nové rozpätie aktívnym. Pri volaní externých služieb sa im odovzdá aktuálny aktívny rozsah a tieto služby vytvoria nové rozsahy s odkazom na tento rozsah.
Všetka práca prechádza cez inštanciu Tracer, môžete ju získať cez mechanizmus DI alebo GlobalTracer.get () ako globálnu premennú, ak mechanizmus DI nefunguje. V predvolenom nastavení, ak tracer nebol inicializovaný, NoopTracer sa vráti, čo nerobí nič.
Ďalej sa aktuálny rozsah získa zo sledovača cez ScopeManager, z aktuálneho sa vytvorí nový rozsah s naviazaním nového rozsahu a potom sa vytvorený rozsah uzavrie, čím sa zatvorí vytvorený rozsah a vráti sa predchádzajúci rozsah na aktívny stav. Rozsah je viazaný na vlákno, takže pri viacvláknovom programovaní nesmiete zabudnúť preniesť aktívny rozsah do iného vlákna, pre ďalšiu aktiváciu rozsahu iného vlákna s odkazom na tento rozsah.

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

Pre viacvláknové programovanie existuje aj TracedExecutorService a podobné wrappery, ktoré automaticky preposielajú aktuálne rozpätie do vlákna pri spustení asynchrónnych úloh:

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

Pre externé http požiadavky existuje TracingHttpClient

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

Problémy, ktorým sme čelili

  • Beans a DI nie vždy fungujú, ak sa sledovač nepoužíva v službe alebo komponente Automaticky zapojené Tracer nemusí fungovať a budete musieť použiť GlobalTracer.get().
  • Anotácie nefungujú, ak nejde o komponent alebo službu, alebo ak je metóda volaná zo susednej metódy rovnakej triedy. Musíte byť opatrní, aby ste skontrolovali, čo funguje, a ak @Traced nefunguje, použite manuálne vytváranie sledovania. Môžete tiež pripojiť ďalší kompilátor pre anotácie Java, potom by mali fungovať všade.
  • V starej jarnej a jarnej obuvi nefunguje automatická konfigurácia jarného cloudu opentraing kvôli chybám v DI, potom ak chcete, aby stopy v pružinových komponentoch fungovali automaticky, môžete to urobiť analogicky s github.com/opentracing-contrib/java-spring-jaeger/blob/master/opentracing-spring-jaeger-starter/src/main/java/io/openracing/contrib/java/spring/jaeger/starter/JaegerAutoConfiguration.java
  • Try with resources nefunguje v groovy, musíte nakoniec použiť try.
  • Každá služba musí mať svoj vlastný spring.application.name, pod ktorým sa budú zaznamenávať stopy. Čo robí samostatný názov pre predaj a test, aby im spolu neprekážali.
  • Ak používate GlobalTracer a kocúra, potom všetky služby spustené v tomto kocúriku majú jeden GlobalTracer, takže všetky budú mať rovnaký názov služby.
  • Pri pridávaní stôp do metódy si musíte byť istí, že nie je volaná mnohokrát v slučke. Pre všetky hovory je potrebné pridať jednu spoločnú stopu, ktorá zaručí celkový čas práce. V opačnom prípade sa vytvorí nadmerné zaťaženie.
  • Raz v jaeger-ui boli príliš veľké požiadavky na veľké množstvo stôp, a keďže nečakali na odpoveď, urobili to znova. Ako výsledok, jaeger-query začal jesť veľa pamäte a spomaľovať elasticitu. Pomohlo reštartovanie jaeger-query

Odber vzoriek, ukladanie a prezeranie stôp

Existujú tri typy vzorkovacie stopy:

  1. Const, ktorý odosiela a ukladá všetky stopy.
  2. Pravdepodobnosť, ktorá filtruje stopy s určitou danou pravdepodobnosťou.
  3. Ratelimiting, ktorý obmedzuje počet stôp za sekundu. Tieto nastavenia môžete nakonfigurovať na klientovi, buď na jaeger-agent alebo na kolektore. Teraz používame const 1 v zásobníku valuátorov, pretože nie je príliš veľa požiadaviek, ale trvajú dlho. V budúcnosti, ak to bude nadmerne zaťažovať systém, môžete to obmedziť.

Ak používate cassandru, v predvolenom nastavení ukladá stopy iba dva dni. Používame ElasticSearch a stopy sú uložené po celú dobu a nie sú odstránené. Pre každý deň je vytvorený samostatný index, napríklad jaeger-service-2019-03-04. V budúcnosti budete musieť nakonfigurovať automatické čistenie starých stôp.

Na zobrazenie stôp potrebujete:

  • Vyberte službu, podľa ktorej chcete filtrovať stopy, napríklad tomcat7-default pre službu, ktorá je spustená v tomcat a nemôže mať svoj vlastný názov.
  • Potom vyberte operáciu, časový interval a minimálnu dobu prevádzky, napríklad od 10 sekúnd, aby sa vykonávali iba dlhé operácie.
    Sledovanie služieb, OpenTracing a Jaeger
  • Choďte na jednu zo stôp a uvidíte, čo sa tam spomalilo.
    Sledovanie služieb, OpenTracing a Jaeger

Tiež, ak je známe nejaké ID požiadavky, potom môžete nájsť sledovanie podľa tohto ID pomocou vyhľadávania značiek, ak je toto ID zaznamenané v rozsahu sledovania.

Záznamy

články

video

Zdroj: hab.com

Pridať komentár