Service Tracing, OpenTracing ir Jaeger

Service Tracing, OpenTracing ir Jaeger

Savo projektuose naudojame mikro paslaugų architektūrą. Kai atsiranda našumo kliūčių, daug laiko praleidžiama žurnalų stebėjimui ir analizei. Registruojant atskirų operacijų laiką į žurnalo failą, paprastai sunku suprasti, kas paskatino šias operacijas iškviesti, sekti veiksmų seką arba vienos operacijos laiko poslinkį kitose paslaugose.

Siekdami sumažinti rankų darbą, nusprendėme naudoti vieną iš sekimo įrankių. Šiame straipsnyje bus aptarta, kaip ir kam galite naudoti sekimą ir kaip mes tai padarėme.

Kokias problemas galima išspręsti naudojant sekimą?

  1. Raskite našumo kliūtis tiek vienoje paslaugoje, tiek visame vykdymo medyje tarp visų dalyvaujančių paslaugų. Pavyzdžiui:
    • Daug trumpų nuoseklių skambučių tarp paslaugų, pavyzdžiui, į geokodavimą arba į duomenų bazę.
    • Ilgas įvesties / išvesties laukimas, pvz., duomenų perkėlimas tinkle arba skaitymas iš disko.
    • Ilgas duomenų analizavimas.
    • Ilgos operacijos, kurioms reikalingas CPU.
    • Kodo skiltys, kurių nereikia galutiniam rezultatui gauti ir kurias galima pašalinti arba paleisti atidėti.
  2. Aiškiai supraskite, kokia tvarka kas vadinama ir kas nutinka, kai atliekama operacija.
    Service Tracing, OpenTracing ir Jaeger
    Matyti, kad, pavyzdžiui, Prašymas atėjo į WS tarnybą -> WS tarnyba papildė duomenis per R tarnybą -> tada išsiuntė užklausą V tarnybai -> V tarnyba atsisiuntė daug duomenų iš R tarnyba -> nuėjo į P servisą -> P tarnyba vėl nuėjo į servisą R -> tarnyba V ignoravo rezultatą ir nuėjo į servisą J -> ir tik tada grąžino atsakymą į paslaugą WS, toliau skaičiuodama kažką kita fonas.
    Be tokio pėdsako ar išsamios dokumentacijos visam procesui, labai sunku suprasti, kas vyksta pirmą kartą pažvelgus į kodą, o kodas yra išbarstytas po įvairias paslaugas ir paslėptas už daugybės pupelių ir sąsajų.
  3. Informacijos apie vykdymo medį rinkimas tolesnei atidėtai analizei. Kiekviename vykdymo etape prie sekimo galite įtraukti informaciją, kuri yra prieinama šiame etape, ir išsiaiškinti, kokie įvesties duomenys lėmė tokį scenarijų. Pavyzdžiui:
    • Vartotojo ID
    • Teisė
    • Pasirinkto metodo tipas
    • Žurnalo arba vykdymo klaida
  4. Pėdsakų pavertimas metrikų pogrupiu ir tolesnė analizė metrikos pavidalu.

Koks sekimas gali prisijungti. Span

Atsekant yra tarpatramio sąvoka, tai yra vieno rąsto ir konsolės analogas. Span turi:

  • Pavadinimas, paprastai atlikto metodo pavadinimas
  • Paslaugos, kurioje buvo sugeneruotas intervalas, pavadinimas
  • Nuosavas unikalus ID
  • Tam tikra metainformacija rakto / vertės forma, kuri buvo įtraukta į ją. Pavyzdžiui, metodo parametrai arba tai, ar metodas baigėsi klaida, ar ne
  • Šios apimties vykdymo pradžios ir pabaigos laikas
  • Pirminio laikotarpio ID

Kiekvienas intervalas siunčiamas į intervalo rinktuvą, kad būtų išsaugotas duomenų bazėje, kad vėliau būtų galima peržiūrėti, kai tik jis baigs vykdyti. Ateityje galėsite sukurti visų tarpatramių medį sujungę juos pagal pirminį ID. Analizuodami galite rasti, pavyzdžiui, visus kai kurių paslaugų, kurie užtruko ilgiau nei šiek tiek laiko, intervalus. Tada, eidami į tam tikrą tarpą, pamatykite visą medį virš ir žemiau šio tarpo.

Service Tracing, OpenTracing ir Jaeger

Opentrace, Jagger ir kaip mes tai įgyvendinome savo projektams

Yra bendras standartas Opentrace, kuriame aprašoma, kaip ir kas turi būti renkama, nesiejant pėdsakų su konkrečiu įgyvendinimu jokia kalba. Pavyzdžiui, „Java“ programoje visas darbas su pėdsakais atliekamas per bendrą „Opentrace“ API, o po juo galima paslėpti, pavyzdžiui, „Jaeger“ arba tuščią numatytąjį diegimą, kuris nieko nedaro.
Mes naudojame Jaeger kaip Opentrace įgyvendinimas. Jį sudaro keli komponentai:

Service Tracing, OpenTracing ir Jaeger

  • „Jaeger-agent“ yra vietinis agentas, kuris paprastai įdiegiamas kiekviename įrenginyje, o paslaugos yra prisijungusios prie jo per vietinį numatytąjį prievadą. Jei agento nėra, tada visų šio įrenginio paslaugų pėdsakai paprastai išjungiami
  • Jaeger-collector – visi agentai siunčia surinktus pėdsakus į jį, o jis įkelia juos į pasirinktą duomenų bazę
  • Duomenų bazė - jų pageidaujama yra cassandra, bet mes naudojame elasticsearch, yra dar kelios duomenų bazės diegimai ir diegimas atmintyje, kuris nieko neišsaugo diske
  • Jaeger-query yra paslauga, kuri patenka į duomenų bazę ir pateikia jau surinktus pėdsakus analizei
  • Jaeger-ui yra žiniatinklio sąsaja, skirta pėdsakų paieškai ir peržiūrai, ji veikia su jaeger-query

Service Tracing, OpenTracing ir Jaeger

Atskiras komponentas gali būti vadinamas opentrace jaeger įgyvendinimu konkrečioms kalboms, per kurį intervalai siunčiami į jaeger-agent.
„Jagger“ prijungimas „Java“. io.opentracing.Tracer sąsaja, po kurios visi pėdsakai per ją nukeliaus į tikrąjį agentą.

Service Tracing, OpenTracing ir Jaeger

Taip pat galite prijungti spyruoklinius komponentus opentracing-spring-cloud-starter ir įgyvendinimas iš Jaeger opentracing-spring-jaeger-cloud-starter kuri automatiškai sukonfigūruos sekimą viskam, kas praeina per šiuos komponentus, pvz., http užklausas valdikliams, užklausas duomenų bazei per jdbc ir kt.

Pėdsakų registravimas Java programoje

Kažkur aukščiausiame lygyje turi būti sukurtas pirmasis Span, tai gali padaryti automatiškai, pavyzdžiui, spyruoklės valdiklis gavęs užklausą arba rankiniu būdu, jei jo nėra. Tada jis perduodamas per toliau pateiktą sritį. Jei pagal kurį nors toliau pateiktą metodą norima pridėti intervalą, jis paima dabartinį aktyvųjį intervalą iš apimties, sukuria naują diapazoną ir sako, kad jo pirminis diapazonas gavo ActiveSpan, o naujasis intervalas tampa aktyvus. Kai iškviečiamos išorinės paslaugos, dabartinis aktyvus intervalas perduodamas joms, o tos paslaugos sukuria naujus su šiuo intervalu susietus intervalus.
Visas darbas vyksta per Tracer egzempliorių; galite jį gauti naudodami DI mechanizmą arba GlobalTracer.get() kaip visuotinį kintamąjį, jei DI mechanizmas neveikia. Pagal numatytuosius nustatymus, jei sekiklis nebuvo inicijuotas, bus grąžintas NoopTracer, kuris nieko nedaro.
Tada esama apimtis gaunama iš sekimo per ScopeManager, iš dabartinės sukuriama nauja apimtis su pridedamu nauju intervalu, o tada sukurta sritis uždaroma, o tai uždaro sukurtą sritį ir grąžina ankstesnę sritį į aktyvią būseną. . Apimtis yra susieta su sriegiu, todėl kai programuojate kelių gijų, turite nepamiršti perkelti aktyvaus intervalo į kitą giją, kad galėtumėte toliau suaktyvinti kitos su šiuo intervalu susietos gijos apimtį.

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

Kelių gijų programavimui taip pat yra „TracedExecutorService“ ir panašūs paketai, kurie automatiškai persiunčia esamą intervalą į giją, kai vykdomos asinchroninės užduotys:

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

Išorinėms http užklausoms yra TracingHttpClient

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

Problemos, su kuriomis susidūrėme

  • Pupelės ir DI ne visada veikia, jei žymeklis nenaudojamas servise ar komponentuose Automatinis laidas Tracer gali neveikti ir turėsite naudoti GlobalTracer.get().
  • Anotacijos neveikia, jei tai nėra komponentas ar paslauga, arba jei metodo iškvietimas gaunamas iš gretimo tos pačios klasės metodo. Turite būti atsargūs, patikrinti, kas veikia, ir naudoti rankinį pėdsakų kūrimą, jei @Traced neveikia. Taip pat galite pridėti papildomą „Java“ komentarų kompiliatorių, tada jis turėtų veikti visur.
  • Esant senam pavasario ir spyruokliniam įkrovimui, opentraing pavasario debesies automatinė konfigūracija neveikia dėl DI klaidų, tada jei norite, kad spyruoklinių komponentų pėdsakai veiktų automatiškai, galite tai padaryti pagal analogiją su 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
  • Bandymas naudojant išteklius neveikia groovy; galiausiai turite naudoti try.
  • Kiekviena paslauga turi turėti savo spring.application.name, pagal kurią bus registruojami pėdsakai. Kaip dėl atskiro pardavimo ir testavimo pavadinimo, kad jų nebūtų maišoma.
  • Jei naudojate GlobalTracer ir tomcat, visos šiame tomcat veikiančios paslaugos turi vieną GlobalTracer, todėl jos visos turės tą patį paslaugos pavadinimą.
  • Pridėdami pėdsakus prie metodo, turite būti tikri, kad jis nėra daug kartų iškviestas cikle. Turite pridėti vieną bendrą visų skambučių pėdsaką, kuris įrašys bendrą veikimo laiką. Priešingu atveju bus sukurta perteklinė apkrova.
  • Kartą Jaeger-ui jie pateikė per didelius prašymus dėl daugybės pėdsakų ir, nelaukę atsakymo, padarė tai dar kartą. Dėl to jaeger užklausa pradėjo valgyti daug atminties ir sulėtinti elastingumą. Padėjo iš naujo paleidus jaeger-query

Mėginių ėmimas, saugojimas ir stebėjimas

Yra trys tipai pėdsakų mėginių ėmimas:

  1. Const, kuris siunčia ir išsaugo visus pėdsakus.
  2. Tikimybinis, kuris filtruoja pėdsakus su tam tikra tikimybe.
  3. Įvertinimas, kuris riboja pėdsakų skaičių per sekundę. Šiuos nustatymus galite konfigūruoti kliente, „jaeger-agent“ arba kolektorius. Dabar vertintojų krūvoje naudojame const 1, nes užklausų nėra labai daug, tačiau jos užtrunka ilgai. Ateityje, jei dėl to sistema bus apkrauta be reikalo, galėsite ją apriboti.

Jei naudojate cassandra, pagal numatytuosius nustatymus ji saugo pėdsakus tik dvi dienas. Mes naudojame elastinga paieška ir pėdsakai saugomi visą laiką ir neištrinami. Kiekvienai dienai sukuriamas atskiras indeksas, pvz., jaeger-service-2019-03-04. Ateityje turėsite sukonfigūruoti automatinį senų pėdsakų valymą.

Norėdami pamatyti pėdsakus, turite:

  • Pasirinkite paslaugą, pagal kurią norite filtruoti pėdsakus, pavyzdžiui, tomcat7-default paslaugai, kuri veikia Tomcat ir negali turėti savo pavadinimo.
  • Tada pasirinkite operaciją, laikotarpį ir minimalų veikimo laiką, pavyzdžiui, nuo 10 sekundžių, kad atliktumėte tik ilgus veiksmus.
    Service Tracing, OpenTracing ir Jaeger
  • Eikite į vieną iš pėdsakų ir pažiūrėkite, kas ten sulėtėjo.
    Service Tracing, OpenTracing ir Jaeger

Be to, jei žinomas koks nors užklausos ID, galite rasti pėdsaką pagal šį ID per žymos paiešką, jei šis ID yra užregistruotas sekimo intervale.

Įrašai

Straipsniai

video

Šaltinis: www.habr.com

Добавить комментарий