Netramesh - lagano servisno mrežno rješenje

Kako prelazimo s monolitne aplikacije na arhitekturu mikroservisa, suočavamo se s novim izazovima.

U monolitnoj aplikaciji obično je prilično lako odrediti u kojem dijelu sustava je došlo do pogreške. Najvjerojatnije je problem u kodu samog monolita ili u bazi podataka. Ali kada počnemo tražiti problem u mikroservisnoj arhitekturi, sve više nije tako očito. Moramo pronaći cijeli put kojim je zahtjev prošao od početka do kraja i odabrati ga među stotinama mikroservisa. Štoviše, mnogi od njih također imaju vlastite skladišne ​​prostore, što također može uzrokovati logičke pogreške, kao i probleme s performansama i tolerancijom na greške.

Netramesh - lagano servisno mrežno rješenje

Dugo sam tražio alat koji bi pomogao u rješavanju takvih problema (o tome sam pisao na Habréu: 1, 2), ali na kraju sam napravio vlastito open source rješenje. U ovom članku govorim o prednostima mrežnog pristupa usluge i dijelim novi alat za njegovu implementaciju.

Distribuirano praćenje je uobičajeno rješenje za problem pronalaženja grešaka u distribuiranim sustavima. Ali što ako ovaj pristup prikupljanju informacija o mrežnim interakcijama još nije implementiran u sustav, ili, još gore, u dijelu sustava već radi ispravno, ali u dijelu ne radi, jer nije dodan starim servisima ? Da bi se utvrdio točan uzrok problema, potrebno je imati potpunu sliku o tome što se događa u sustavu. Osobito je važno razumjeti koje su mikrousluge uključene u ključne poslovne putove.

Ovdje nam u pomoć može priskočiti servisni mrežni pristup, koji će se baviti svim strojevima za prikupljanje mrežnih informacija na razini nižoj od one koju rade same usluge. Ovaj pristup nam omogućuje da presretnemo sav promet i analiziramo ga u hodu. Štoviše, aplikacije čak ne moraju ništa znati o tome.

Mrežni pristup usluge

Glavna ideja uslužnog mrežnog pristupa je dodavanje još jednog infrastrukturnog sloja preko mreže, što će nam omogućiti da radimo bilo što s interakcijom između usluga. Većina implementacija radi na sljedeći način: dodatni bočni spremnik s transparentnim proxyjem dodaje se svakoj mikroservisi, kroz koju prolazi sav dolazni i odlazni promet usluge. A upravo je to mjesto gdje možemo raditi balansiranje klijenata, primjenjivati ​​sigurnosne politike, postavljati ograničenja na broj zahtjeva i prikupljati važne informacije o interakciji usluga u proizvodnji.

Netramesh - lagano servisno mrežno rješenje

rješenja

Već postoji nekoliko implementacija ovog pristupa: Istio и povezivač2. Pružaju puno značajki odmah po otvaranju. Ali u isto vrijeme dolazi do velikih troškova za resurse. Štoviše, što je veći klaster u kojem takav sustav radi, to će više resursa biti potrebno za održavanje nove infrastrukture. U Avitu upravljamo kubernetes klasterima koji sadrže tisuće servisnih instanci (i njihov broj nastavlja ubrzano rasti). U svojoj trenutnoj implementaciji, Istio troši ~300Mb RAM-a po instanci usluge. Zbog velikog broja mogućnosti, transparentno balansiranje utječe i na ukupno vrijeme odziva usluga (do 10ms).

Kao rezultat toga, pogledali smo koje su nam mogućnosti upravo sada potrebne i odlučili da je glavni razlog zašto smo počeli implementirati takva rješenja mogućnost transparentnog prikupljanja podataka o praćenju iz cijelog sustava. Također smo htjeli imati kontrolu nad interakcijom servisa i raditi razne manipulacije sa zaglavljima koja se prenose između servisa.

Kao rezultat toga, došli smo do naše odluke:  Netramesh.

Netramesh

Netramesh je lagano servisno mrežno rješenje s mogućnošću beskonačnog skaliranja, bez obzira na broj servisa u sustavu.

Glavni ciljevi novog rješenja bili su niska potrošnja resursa i visoka izvedba. Među glavnim značajkama, odmah smo željeli mogućnost transparentnog slanja raspona praćenja u naš Jaeger sustav.

Danas je većina rješenja u oblaku implementirana u Golangu. I, naravno, postoje razlozi za to. Pisanje mrežnih aplikacija u Golangu koje rade asinkrono s I/O i skaliraju preko jezgri po potrebi je zgodno i prilično jednostavno. I što je također vrlo važno, performanse su dovoljne za rješavanje ovog problema. Zato smo i mi odabrali Golang.

Performanse

Naše smo napore usmjerili na postizanje maksimalne produktivnosti. Za rješenje koje se postavlja uz svaku instancu usluge potrebna je mala potrošnja RAM-a i CPU vremena. I, naravno, kašnjenje odgovora također bi trebalo biti malo.

Da vidimo kakve smo rezultate dobili.

RAM

Netramesh troši ~10Mb bez prometa i 50Mb maksimalno uz opterećenje do 10000 RPS po instanci.

Istio envoy proxy uvijek troši ~300Mb u našim klasterima s tisućama instanci. To ne dopušta skaliranje na cijeli klaster.

Netramesh - lagano servisno mrežno rješenje

Netramesh - lagano servisno mrežno rješenje

Uz Netramesh dobili smo ~10x smanjenje potrošnje memorije.

CPU

Upotreba CPU-a je relativno jednaka pod opterećenjem. Ovisi o broju zahtjeva po jedinici vremena prema prikolici. Vrijednosti pri 3000 zahtjeva u sekundi na vrhuncu:

Netramesh - lagano servisno mrežno rješenje

Netramesh - lagano servisno mrežno rješenje

Postoji još jedna važna točka: Netramesh - rješenje bez kontrolne ravnine i bez opterećenja ne troši CPU vrijeme. Uz Istio, sidecars uvijek ažuriraju krajnje točke usluge. Kao rezultat, možemo vidjeti ovu sliku bez opterećenja:

Netramesh - lagano servisno mrežno rješenje

Koristimo HTTP/1 za komunikaciju između usluga. Povećanje vremena odgovora za Istio pri proxyju preko envoyja bilo je do 5-10 ms, što je dosta za servise koji su spremni odgovoriti u milisekundi. Uz Netramesh ovo se vrijeme smanjilo na 0.5-2 ms.

Skalabilnost

Mala količina resursa koje troši svaki proxy omogućuje njegovo postavljanje uz svaku uslugu. Netramesh je namjerno stvoren bez komponente kontrolne ravnine kako bi svaka prikolica bila lagana. Često u servisnim mrežastim rješenjima, upravljačka ravnina distribuira informacije o otkrivanju servisa svakoj prikolici. Zajedno s njim dolaze informacije o vremenskim ograničenjima i postavkama balansiranja. Sve to vam omogućuje da radite puno korisnih stvari, ali, nažalost, povećava veličinu bočnih prikolica.

Otkrivanje usluge

Netramesh - lagano servisno mrežno rješenje

Netramesh ne dodaje nikakve dodatne mehanizme za otkrivanje usluge. Sav promet proksira se transparentno kroz netra sidecar.

Netramesh podržava HTTP/1 aplikacijski protokol. Za definiranje se koristi popis portova koji se može konfigurirati. Tipično, sustav ima nekoliko portova kroz koje se odvija HTTP komunikacija. Na primjer, za interakciju između usluga i vanjskih zahtjeva koristimo 80, 8890, 8080. U ovom slučaju, oni se mogu postaviti pomoću varijable okruženja NETRA_HTTP_PORTS.

Ako koristite Kubernetes kao orkestrator i njegov mehanizam entiteta usluge za komunikaciju unutar klastera između usluga, tada mehanizam ostaje potpuno isti. Prvo, mikroservis dobiva IP adresu servisa koristeći kube-dns i otvara novu vezu s njim. Ova se veza prvo uspostavlja s lokalnom netra-sidecar i svi TCP paketi inicijalno stižu na netru. Zatim, netra-sidecar uspostavlja vezu s izvornim odredištem. NAT na pod IP na čvoru ostaje potpuno isti kao i bez netre.

Distribuirano praćenje i prosljeđivanje konteksta

Netramesh pruža funkcionalnost potrebnu za slanje raspona praćenja o HTTP interakcijama. Netra-sidecar analizira HTTP protokol, mjeri kašnjenja zahtjeva i izvlači potrebne informacije iz HTTP zaglavlja. U konačnici, dobivamo sve tragove u jednom Jaeger sustavu. Za preciznu konfiguraciju možete koristiti i varijable okruženja koje pruža službena biblioteka jaeger go knjižnica.

Netramesh - lagano servisno mrežno rješenje

Netramesh - lagano servisno mrežno rješenje

Ali postoji problem. Sve dok usluge ne generiraju i pošalju posebno uber zaglavlje, nećemo vidjeti povezane raspone praćenja u sustavu. A to je ono što nam je potrebno da brzo pronađemo uzrok problema. I ovdje Netramesh ima rješenje. Proxiji čitaju HTTP zaglavlja i, ako ne sadrže uber ID praćenja, generiraju ga. Netramesh također pohranjuje informacije o dolaznim i odlaznim zahtjevima u sidecar i uspoređuje ih obogaćujući ih potrebnim zaglavljima odlaznih zahtjeva. Sve što trebate učiniti u uslugama je poslati samo jedno zaglavlje X-Request-Id, koji se može konfigurirati pomoću varijable okruženja NETRA_HTTP_REQUEST_ID_HEADER_NAME. Da biste kontrolirali veličinu konteksta u Netrameshu, možete postaviti sljedeće varijable okruženja: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS (vrijeme za koje će kontekst biti pohranjen) i NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL (učestalost čišćenja konteksta).

Također je moguće kombinirati više staza na vašem sustavu tako da ih označite posebnim tokenom sesije. Netra vam omogućuje instalaciju HTTP_HEADER_TAG_MAP za pretvaranje HTTP zaglavlja u odgovarajuće oznake raspona praćenja. Ovo može biti posebno korisno za testiranje. Nakon što prođete funkcionalni test, možete vidjeti na koji je dio sustava utjecalo filtriranje odgovarajućim ključem sesije.

Određivanje izvora zahtjeva

Da biste utvrdili odakle je zahtjev došao, možete koristiti funkciju automatskog dodavanja zaglavlja s izvorom. Korištenje varijable okruženja NETRA_HTTP_X_SOURCE_HEADER_NAME Možete odrediti naziv zaglavlja koji će se automatski instalirati. Pomoću NETRA_HTTP_X_SOURCE_VALUE možete postaviti vrijednost na koju će biti postavljeno zaglavlje X-Source za sve odlazne zahtjeve.

Ovo omogućuje da se distribucija ovog korisnog zaglavlja ravnomjerno distribuira kroz mrežu. Zatim ga možete koristiti u uslugama i dodati u zapisnike i metriku.

Usmjeravanje prometa i interni Netramesh

Netramesh se sastoji od dvije glavne komponente. Prvi, netra-init, postavlja mrežna pravila za presretanje prometa. On koristi iptables pravila preusmjeravanja za presretanje cijelog ili dijela prometa na bočnoj prikolici, što je druga glavna komponenta Netramesha. Možete konfigurirati koji portovi moraju biti presretnuti za dolazne i odlazne TCP sesije: INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS.

Alat također ima zanimljivu značajku - probabilističko rutiranje. Ako koristite Netramesh isključivo za prikupljanje raspona praćenja, tada u proizvodnom okruženju možete uštedjeti resurse i omogućiti vjerojatnosno usmjeravanje pomoću varijabli NETRA_INBOUND_PROBABILITY и NETRA_OUTBOUND_PROBABILITY (od 0 do 1). Zadana vrijednost je 1 (sav promet se presreće).

Nakon uspješnog presretanja, netra sidecar prihvaća novu vezu i koristi se SO_ORIGINAL_DST opciju utičnice za dobivanje izvornog odredišta. Netra zatim otvara novu vezu na izvornu IP adresu i uspostavlja dvosmjernu TCP komunikaciju između strana, slušajući sav promet koji prolazi. Ako je port definiran kao HTTP, Netra ga pokušava analizirati i pratiti. Ako HTTP parsiranje ne uspije, Netra se vraća na TCP i transparentno proksira bajtove.

Izgradnja grafa ovisnosti

Nakon što sam primio veliku količinu podataka o praćenju u Jaegeru, želim dobiti potpuni grafikon interakcija u sustavu. Ali ako je vaš sustav prilično opterećen i milijarde raspona praćenja se akumuliraju dnevno, njihovo prikupljanje postaje ne tako lak zadatak. Postoji službeni način za to: ovisnosti o iskri. Međutim, bit će potrebni sati da se napravi kompletan grafikon i morat ćete preuzeti cijeli skup podataka s Jaegera za posljednja XNUMX sata.

Ako koristite Elasticsearch za pohranjivanje raspona praćenja, možete koristiti jednostavan Golang uslužni program, koji će izgraditi isti grafikon u nekoliko minuta koristeći značajke i mogućnosti Elasticsearcha.

Netramesh - lagano servisno mrežno rješenje

Kako koristiti Netramesh

Netra se može jednostavno dodati bilo kojoj usluzi koja pokreće bilo koji orkestrator. Možete vidjeti primjer ovdje.

Trenutačno Netra nema mogućnost automatske implementacije prikolica na usluge, ali postoje planovi za implementaciju.

Budućnost Netramesha

Glavni cilj Netramesh je postići minimalne troškove resursa i visoku izvedbu, pružajući osnovne sposobnosti za promatranje i kontrolu komunikacije između usluga.

U budućnosti će Netramesh podržavati i druge protokole aplikacijskog sloja osim HTTP-a. L7 usmjeravanje bit će dostupno u bliskoj budućnosti.

Koristite Netramesh ako naiđete na slične probleme i pišite nam s pitanjima i prijedlozima.

Izvor: www.habr.com

Dodajte komentar