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ą?
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.
Aiškiai supraskite, kokia tvarka kas vadinama ir kas nutinka, kai atliekama operacija.
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ų.
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
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.
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:
„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
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ą.
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į.
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()
);
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.
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
Tikimybinis, kuris filtruoja pėdsakus su tam tikra tikimybe.
Į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.
Eikite į vieną iš pėdsakų ir pažiūrėkite, kas ten sulėtėjo.
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.