Në procesin e kalimit nga aplikacioni monolitik në arkitekturën mikroshërbimeve, ne përballemi me probleme të reja.
Në një aplikacion monolitik, zakonisht mjafton të përcaktohet se në cilën pjesë të sistemit ndodhi gabimi. Më shumë mundësi, problemi është në kodin e vetë monolitit ose në bazën e të dhënave. Por kur fillojmë të kërkojmë problemin në arkitekturën mikroshërbimeve, gjërat nuk janë aq të qarta. Duhet të gjejmë të gjithë rrugën që ka bërë kërkesa nga fillimi në fund, duke e ndarë atë nga qindra mikroshërbime. Për më tepër, shumë prej tyre kanë ruajtje të vetat, ku gjithashtu mund të ndodhin gabime logjike, si dhe probleme me performancën dhe disponueshmërinë.

Kam kërkuar gjatë për një mjet që do të ndihmonte të merrej me këto probleme (kam shkruar për këtë në Habra: , ), por në fund krijova një zgjidhje të vetën me burim të hapur. Në këtë artikull, tregoj për avantazhet e qasjes service mesh dhe ndaja një mjet të ri për implementimin e saj.
Përgjimi i shpërndarë është një zgjidhje e zakonshme për problemin e gjetjes së gabimeve në sistemet e shpërndara. Por çfarë ndodh nëse në sistem ende nuk është implementuar një qasje e tillë për mbledhjen e informacionit mbi ndërveprimet rrjetërore, ose, çfarë është më keq, në një pjesë të sistemit, ajo tashmë funksionon siç duhet, ndërsa në një pjesë tjetër nuk është e instaluar, pasi nuk është shtuar në shërbimet e vjetra? Për të përcaktuar shkakun e saktë të problemit, është e nevojshme të kemi një pamje të plotë të asaj që ndodh në sistem. Sidomos e rëndësishme është të kuptojmë se cilat mikroshërbime janë të angazhuara në rrugët kryesore kritike për biznesin.
Këtu na ndihmon qasja service mesh, e cila do të merret me gjithë mekanizmin e mbledhjes së informacionit rrjetor në një nivel më të ulët se sa funksionojnë vetë shërbimet. Kjo qasje na lejon të kapim të gjithë trafikun dhe ta analizojmë atë në kohë reale. Madje, aplikacionet as nuk duhet të dinë ndonjë gjë për të.
Qasja service mesh
Ideja kryesore e qasjes në service mesh është shtimi i një shtrese tjetër infrastrukturore mbi rrjetin, e cila na lejon të bëjmë gjithçka me ndërveprimin midis shërbimeve. Shumica e realizimeve funksionojnë si më poshtë: për çdo mikrosherbim shtohet një kontejner sidecar shtesë me një proxy transparent, përmes të cilit kalon e gjithë trafiku hyrës dhe dalës i shërbimit. Dhe kjo është pikërisht ajo ku mund të bëjmë balancimin e klientit, të aplikojmë politika sigurie, të vendosim kufizime mbi numrin e kërkesave dhe të mbledhim informacion të rëndësishëm mbi ndërveprimin e shërbimeve në produksion.

Zgjidhjet
Tashmë ekzistojnë disa realizime të këtij qasjeje: dhe . Ato ofrojnë shumë mundësi nga kutia. Por përkrah kësaj vjen gjithashtu dhe një overhead i madh në burime. Për më tepër, sa më i madh të jetë klasteri në të cilin punon një sistem i tillë, aq më shumë burime do të kërkohen për mbështetje të infrastrukturës së re. Në Avito ne shfrytëzojmë klastere Kubernetes, në të cilat ndodhen mijëra ekzemplarë shërbimesh (dhe numri vazhdon të rritet shpejt). Në realizimin aktual Istio konsumon rreth 300Mb memorie operative për çdo ekzemplar shërbimi. Për shkak të numrit të madh të mundësive, balancimi transparent gjithashtu ndikon në kohën totale të përgjigjes së shërbimeve (deri në 10ms).
Si rezultat, ne shqyrtuam se cilat mundësi na nevojiten pikërisht tani dhe vendosëm se arsyeja kryesore pse filluam të implementonim zgjidhje të tilla ishte mundësia për të mbledhur informacion tracing nga gjithë sistemi në mënyrë transparente. Po ashtu, dëshironim të kishim kontroll mbi ndërveprimin e shërbimeve dhe të bënim manipulime të ndryshme me titujt që kalojnë midis shërbimeve.
Si rezultat, ne arritëm në zgjidhjen tonë: .
Netramesh
â Ă«shtĂ« njĂ« zgjidhje e lehtĂ« service mesh me mundĂ«si pĂ«r shkallĂ«zim tĂ« pakufizuar, pavarĂ«sisht nga numri i shĂ«rbimeve nĂ« sistem.
Qëllimet kryesore të zgjidhjes së re ishin një overhead i vogël në burime dhe performancë e lartë. Nga mundësitë kryesore, ne dëshironim menjëherë të kishim mundësinë të dërgonim transparente tracing span në sistemin tonë Jaeger.
Sot tërhoqur sot, shumica e zgjidhjeve cloud realizohen në Golang. Dhe, natyrisht, ka disa arsye për këtë. Të shkruash aplikacione rrjetë në Golang, të cilat punojnë asinkronisht me hyrje-dalje dhe zgjerohen sipas nevojës në bërthamat, është e përshtatshme dhe mjaft e thjeshtë. Dhe, çka është gjithashtu shumë e rëndësishme, performanca rezulton të jetë e mjaftueshme për të zgjidhur këtë detyrë. Prandaj, ne gjithashtu zgjodhëm Golang.
Performanca
Ne fokusohemi në arritjen e performancës maksimale. Për zgjidhjen që deployohet afër çdo instance të shërbimit, nevojitet pak konsum i memories dhe kohë procesorike. Dhe, natyrisht, vonesa në përgjigje gjithashtu duhet të jetë sa më e vogël.
Le të shikojmë se cilat rezultate kemi arritur.
RAM
Netramesh konsumon ~10Mb pa trafik dhe deri në 50Mb maksimalisht me ngarkesë deri në 10000 RPS për çdo instancë.
Istio envoy proxy gjithmonë konsumon ~300Mb në klasterët tanë me mijëra instanca. Kjo nuk lejon që ta shkallëzojmë atë në të gjithë klasterin.


Me Netramesh kemi arritur një reduktim të konsumit të memories me ~10 herë.
CPU
Përdorimi i CPU-së është relativisht i njëjtë nën ngarkesë. Ajo varet nga numri i kërkesave në njësi kohe për sidecar. Vlerat në 3000 kërkesa në sekondë në pikë:


Ka një moment tjetër të rëndësishëm: Netramesh është një zgjidhje pa plan kontrolli dhe pa ngarkesë nuk konsumon kohë procesorike. Në Istio, sidecar-et gjithmonë përditësojnë endpoint-et e shërbimeve. Si rezultat, mund të shohim këtë pamje pa ngarkesë:

Ne përdorim HTTP/1 për ndërveprimin midis shërbimeve. Rritja e kohës së përgjigjes te Istio kur proksionohet përmes envoy ishte deri në 5-10ms, që është mjaft shumë për shërbimet që janë të gatshme të përgjigjen brenda një milisekunde. Me Netramesh, ky kohë është reduktuar në 0.5-2ms.
Shkallëzueshmëria
Një numër i vogël burimesh të shpenzuara nga çdo proxy lejon që ta vendosim atë afër çdo shërbimi. Netramesh është krijuar qëllimisht pa komponentin e planit të kontrollit për të mbajtur lehtësinë e çdo sidecar-i. Shpesh në zgjidhjet e service mesh, plani i kontrollit shpërndan informacionin e zbulimit të shërbimeve në çdo sidecar. Me të vjen gjithashtu informacioni rreth timeout-eve, konfigurimeve të balancimit. Të gjitha këto lejojnë të bëhen shumë gjëra të dobishme, por, fatkeqësisht, fryjnë sidecarët në madhësi.
Zbulimi i shërbimeve

Netramesh nuk shton asnjë mekanizëm shtesë për zbulimin e shërbimeve. Të gjithë trafiku proksionohet në mënyrë transparente përmes netra sidecar.
Netramesh mbështet protokollin e aplikacionit HTTP/1. Për ta përcaktuar, përdoret një listë portesh të konfigurueshme. Zakonisht në sistem ka disa porte, me të cilat ndodhin ndërveprime nëpërmjet HTTP. Për shembull, për ndërveprimin e shërbimeve dhe kërkesave të jashtme, ne përdorim 80, 8890, 8080. Në këtë rast, ata mund të përcaktohen me anë të variablit të mjedisit NETRA_HTTP_PORTS.
Nëse po përdorni Kubernetes si orkestrator dhe mekanizmin e tij të entiteteve Shërbim për ndërveprimin brenda grumbullit midis shërbimeve, atëherë mekanizmi mbetet sexact kështu. Fillimisht, mikroshërbimi merr adresën IP të shërbimit përmes kube-dns dhe hap një lidhje të re me të. Kjo lidhje krijohet fillimisht me netra-sidecar lokal dhe të gjithë paketat TCP fillimisht arrijnë saktësisht në netra. Më pas, netra-sidecar krijon lidhjen me pikën e origjinës. NAT në pod IP në nod mbetet sexact ashtu si pa netra.
Ndjekja e shpërndarë dhe kalimi i kontekstit
Netramesh ofron funksionalitetin e nevojshëm për dërgimin e span'ëve të ndjekjes për ndërveprimin HTTP. Netra-sidecar analizojnë protokollin HTTP, masin vonesat e kërkesave, nxjerrin informacionin e nevojshëm nga header-at HTTP. Në fund, ne marrim të gjitha ndjekjet në një sistem të vetëm Jaeger. Për konfigurim të hollësishëm, mund të përdoren gjithashtu variablat e mjedisit që ofron biblioteka zyrtare .


Por ka njĂ« problem. Derisa shĂ«rbimet tĂ« fillojnĂ« tĂ« gjenerojnĂ« dhe kalojnĂ« njĂ« header tĂ« veçantĂ« uber, ne nuk do tĂ« shohim span'Ă«t e ndjekjes tĂ« lidhur nĂ« sistem. Dhe kjo Ă«shtĂ« ajo qĂ« na nevojitet pĂ«r tĂ« gjetur shpejt shkakun e problemeve. KĂ«tu Netramesh pĂ«rsĂ«ri ka njĂ« zgjidhje. Proxy-t lexojnĂ« header-at HTTP dhe, nĂ«se ato nuk kanĂ« uber trace id, e gjenerojnĂ« atĂ«. Netramesh gjithashtu ruan informacionin mbi kĂ«rkesat hyrĂ«se dhe dalĂ«se nĂ« sidecar dhe i korrespondon ato duke i pasuruar me header-at e nevojshĂ«m tĂ« kĂ«rkesave dalĂ«se. ĂfarĂ«do qĂ« duhet tĂ« bĂ«ni nĂ« shĂ«rbime Ă«shtĂ« tĂ« kaloni vetĂ«m njĂ« header X-Request-Id, i cili mund tĂ« konfigurohet me anĂ« tĂ« variablit tĂ« mjedisit NETRA_HTTP_REQUEST_ID_HEADER_NAME. PĂ«r tĂ« menaxhuar madhĂ«sinĂ« e kontekstit nĂ« Netramesh, mund tĂ« pĂ«rcaktoni variablit e mjedisit tĂ« mĂ«poshtĂ«m: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS (koha brenda sĂ« cilĂ«s do tĂ« ruhet konteksti) dhe NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL (frekuenca e pastrimit tĂ« kontekstit).
Gjithashtu është e mundur të kombinoni disa rrugë në sistemin tuaj duke i ndikuar ato me një marker të veçantë sesioni. Netra lejon vendosjen HTTP_HEADER_TAG_MAP për të kthyer headerat HTTP në tags përkatëse të tracing span. Kjo mund të jetë veçanërisht e dobishme për testimin. Pas përfundimit të një testi funksional, mund të shikoni se cila pjesë e sistemit është prekur, duke filtruar sipas çelësit të sesionit përkatës.
Përcaktimi i burimit të kërkesës
Për të përcaktuar nga vjen kërkesa, mund të përdorni funksionalitetin e shtimit automatik të headerit me burimin. Me ndihmën e variablit të ambientit NETRA_HTTP_X_SOURCE_HEADER_NAME mund të përcaktoni emrin e headerit që do të vendoset automatikisht. Me NETRA_HTTP_X_SOURCE_VALUE mund të përcaktoni vlerën në të cilën do të vendoset headeri X-Source për të gjitha kërkesat që dalin.
Kjo lejon shpërndarjen e këtij headeri të dobishëm në mënyrë uniforme në të gjithë rrjetin. Më pas, mund ta përdorni atë në shërbime dhe ta ndani në loge, metrika.
Rruga e trafik dhe brendësia e Netramesh
Netramesh pĂ«rbĂ«het nga dy komponentĂ« kryesorĂ«. I pari, netra-init, vendos rregullat e rrjetit pĂ«r tĂ« kapur trafikun. Ai pĂ«rdor INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS Po ashtu, nĂ« mjet ekziston njĂ« mundĂ«si interesante â rrugĂ«zim probabilistik. NĂ«se pĂ«rdorni Netramesh ekskluzivisht pĂ«r tĂ« mbledhur tracing span, mund tĂ« kurseni burime nĂ« mjedisin e prodhimit dhe tĂ« aktivizoni rrugĂ«zimin probabilistik me ndihmĂ«n e variablave.
NETRA_INBOUND_PROBABILITY NETRA_OUTBOUND_PROBABILITY dhe (nga 0 në 1). Vlera e paracaktuar është 1 (kapet të gjithë trafiku). Pas kapjes së suksesshme, netra sidecar merr një lidhje të re dhe përdor
SO_ORIGINAL_DST opsionin e soketave për të marrë pikën origjinale të destinacionit. Më pas, Netra hap një lidhje të re me adresën IP origjinale dhe vendos një komunikim TCP të dyanshëm midis palëve, duke dëgjuar të gjithë trafikun që kalon. Nëse porti është përcaktuar si HTTP, Netra përpiqet ta analizojë dhe ta gjurmojë. Nëse analiza e HTTP dështlon, Netra kalon në TCP dhe transparen të prokson byte të dhëna. Ashtu si dhe në rregullat e sipërm, për të krijuar lidhje të reja me sistemin origjinal.
Ndërtimi i grafit të varësive
Pas marrjes sĂ« njĂ« sasie tĂ« madhe informacioni tracing nĂ« Jaeger, dĂ«shirohet tĂ« marrĂ«ni njĂ« grafik tĂ« plotĂ« tĂ« ndĂ«rveprimeve nĂ« sistem. Por nĂ«se sistemi juaj Ă«shtĂ« mjaft e ngarkuar dhe nĂ« njĂ« ditĂ« grumbullohen miliarda spanâash tracing, agregimi i tyre bĂ«het njĂ« detyrĂ« e komplikuar. Ka njĂ« metodĂ« zyrtare pĂ«r kĂ«tĂ«: . MegjithatĂ« do tĂ« marrĂ« disa orĂ« pĂ«r tĂ« ndĂ«rtuar grafikun e plotĂ« dhe do t'ju detyrojĂ« tĂ« shkarkoni tĂ« gjithĂ« dataset-in nga Jaeger pĂ«r 24 orĂ«t e fundit.
NĂ«se pĂ«rdorni Elasticsearch pĂ«r ruajtjen e spanâave tracing, mund tĂ« shfrytĂ«zoni , i cili do tĂ« ndĂ«rtojĂ« njĂ« grafik tĂ« tillĂ« brenda disa minutash, duke pĂ«rdorur veçoritĂ« dhe mundĂ«sitĂ« e Elasticsearch.

Si të përdorni Netramesh
Netrën mund ta shtoni lehtësisht në çdo shërbim që funksionon nën menaxhimin e çdo orkestratori. Mund të shihni një shembull .
NĂ« kĂ«tĂ« moment, Netra sâka mundĂ«si pĂ«r integrim automatik tĂ« sidecarâit me shĂ«rbimet, por ka plane pĂ«r zbatimin e tij.
E ardhmja e Netramesh
Qëllimi kryesor është arritja e kostove minimale të burimeve dhe performancë e lartë, duke ofruar mundësi kryesore për observability dhe kontrollin e ndërveprimit midis shërbimeve.
Në të ardhmen, Netramesh do të ketë mbështetje për protokolle të tjera të nivelit aplikativ përveç HTTP. Në të ardhmen e afërt do të ketë mundësi të routing L7.
Përdorni Netramesh nëse përballeni me probleme të tilla dhe shkruani pyetje dhe sugjerime.
Burimi: habr.com
