Netramesh - malpeza serva maŝo-solvo

Dum ni transiras de monolita aplikaĵo al mikroserva arkitekturo, ni alfrontas novajn defiojn.

En monolita aplikaĵo, estas kutime sufiĉe facile determini en kiu parto de la sistemo okazis la eraro. Plej verŝajne, la problemo estas en la kodo de la monolito mem, aŭ en la datumbazo. Sed kiam ni komencas serĉi problemon en mikroserva arkitekturo, ĉio ne plu estas tiel evidenta. Ni devas trovi la tutan vojon, kiun la peto prenis de komenco ĝis fino kaj elekti ĝin el centoj da mikroservoj. Krome, multaj el ili ankaŭ havas siajn proprajn stokejojn, kiuj ankaŭ povas kaŭzi logikajn erarojn, kaj ankaŭ problemojn kun rendimento kaj misfunkciado.

Netramesh - malpeza serva maŝo-solvo

Mi delonge serĉas ilon, kiu helpus trakti tiajn problemojn (mi skribis pri tio ĉe Habré: 1, 2), sed finfine mi faris mian propran malfermfontan solvon. En ĉi tiu artikolo mi parolas pri la avantaĝoj de la servo mesh aliro kaj dividas novan ilon por ĝia efektivigo.

Distribuita paŭsaĵo estas ofta solvo al la problemo de trovado de eraroj en distribuitaj sistemoj. Sed kio se ĉi tiu aliro al kolektado de informoj pri retaj interagoj ankoraŭ ne estis efektivigita en la sistemo, aŭ, pli malbone, en parto de la sistemo ĝi jam funkcias ĝuste, sed parte ne funkcias, ĉar ĝi ne estis aldonita al malnovaj servoj ? Por determini la ĝustan radikan kaŭzon de problemo, necesas havi kompletan bildon pri tio, kio okazas en la sistemo. Estas speciale grave kompreni, kiuj mikroservoj estas implikitaj en ŝlosilaj komercaj kritikaj vojoj.

Ĉi tie povas veni al nia helpo la servo-maŝo, kiu traktos la tutan maŝinaron por kolekti retajn informojn je nivelo pli malalta ol la servoj mem funkcias. Ĉi tiu aliro permesas al ni kapti la tutan trafikon kaj analizi ĝin sur la flugo. Krome, aplikaĵoj eĉ ne devas scii ion pri ĝi.

Serva maŝo alproksimiĝo

La ĉefa ideo de la servo-maŝo-aliro estas aldoni alian infrastrukturan tavolon tra la reto, kio permesos al ni fari ion ajn kun inter-serva interago. Plej multaj efektivigoj funkcias jene: al ĉiu mikroservo estas aldonita kroma kroma ujo kun travidebla prokurilo, tra kiu la tuta envenanta kaj elira trafiko de la servo estas trapasita. Kaj ĉi tiu estas la loko, kie ni povas fari klientan ekvilibron, apliki sekurecpolitikojn, trudi limigojn pri la nombro da petoj kaj kolekti gravajn informojn pri la interago de servoj en produktado.

Netramesh - malpeza serva maŝo-solvo

Solvoj

Jam ekzistas pluraj efektivigoj de ĉi tiu aliro: Istio и linkerd2. Ili provizas multajn funkciojn el la skatolo. Sed samtempe venas granda ŝarĝo pri rimedoj. Krome, ju pli granda estas la areto en kiu tia sistemo funkcias, des pli da rimedoj estos postulataj por konservi la novan infrastrukturon. Ĉe Avito, ni funkciigas kubernetes-grupojn, kiuj enhavas milojn da servokazoj (kaj ilia nombro daŭre kreskas rapide). En ĝia nuna efektivigo, Istio konsumas ~300Mb da RAM per servokazaĵo. Pro la granda nombro da eblecoj, travidebla ekvilibro ankaŭ influas la totalan respondtempon de servoj (ĝis 10ms).

Kiel rezulto, ni rigardis precize kiajn kapablojn ni bezonas nun, kaj decidis ke la ĉefa kialo kial ni komencis efektivigi tiajn solvojn estis la kapablo kolekti spurajn informojn de la tuta sistemo travideble. Ni ankaŭ volis havi kontrolon pri la interago de servoj kaj fari diversajn manipuladojn kun la kaplinioj kiuj estas translokigitaj inter servoj.

Kiel rezulto, ni venis al nia decido:  Netramesh.

Netramesh

Netramesh estas malpeza serva maŝo-solvo kun la kapablo grimpi senfine, sendepende de la nombro da servoj en la sistemo.

La ĉefaj celoj de la nova solvo estis malalta resursa superkosto kaj alta rendimento. Inter la ĉefaj trajtoj, ni tuj volis povi travideble sendi spurajn intervalojn al nia Jaeger-sistemo.

Hodiaŭ, plej multaj nubaj solvoj estas efektivigitaj en Golang. Kaj, kompreneble, estas kialoj por ĉi tio. Verki retajn aplikaĵojn en Golang, kiuj funkcias nesinkrone kun I/O kaj skalas trans kernoj laŭbezone, estas oportuna kaj sufiĉe simpla. Kaj, kio ankaŭ estas tre grava, la agado sufiĉas por solvi ĉi tiun problemon. Tial ni ankaŭ elektis Golangon.

Produkteco

Ni koncentris niajn klopodojn atingi maksimuman produktivecon. Por solvo, kiu estas deplojita apud ĉiu okazo de la servo, necesas malgranda konsumo de RAM kaj CPU-tempo. Kaj, kompreneble, la responda prokrasto ankaŭ devus esti malgranda.

Ni vidu kiajn rezultojn ni ricevis.

RAM

Netramesh konsumas ~10Mb sen trafiko kaj 50Mb maksimume kun ŝarĝo de ĝis 10000 RPS per okazo.

Istio sendita prokurilo ĉiam konsumas ~300Mb en niaj aretoj kun miloj da okazoj. Ĉi tio ne permesas al ĝi esti skalita al la tuta areto.

Netramesh - malpeza serva maŝo-solvo

Netramesh - malpeza serva maŝo-solvo

Kun Netramesh ni akiris ~10x redukton en memorkonsumo.

CPU

CPU-uzo estas relative egala sub ŝarĝo. Ĝi dependas de la nombro da petoj po unuo de tempo al la kromĉaro. Valoroj ĉe 3000 petoj je sekundo maksimume:

Netramesh - malpeza serva maŝo-solvo

Netramesh - malpeza serva maŝo-solvo

Estas unu pli grava punkto: Netramesh - solvo sen kontrolaviadilo kaj sen ŝarĝo ne konsumas CPU-tempon. Kun Istio, kromĉaroj ĉiam ĝisdatigas servofinpunktojn. Kiel rezulto, ni povas vidi ĉi tiun bildon sen ŝarĝo:

Netramesh - malpeza serva maŝo-solvo

Ni uzas HTTP/1 por komunikado inter servoj. La pliiĝo de responda tempo por Istio dum prokurado per sendito estis ĝis 5-10ms, kio estas sufiĉe multe por servoj, kiuj pretas respondi en milisekundo. Kun Netramesh ĉi tiu tempo malpliiĝis al 0.5-2ms.

Skalebleco

La malgranda kvanto da rimedoj konsumitaj de ĉiu prokurilo ebligas meti ĝin apud ĉiu servo. Netramesh estis intencite kreita sen kontrolaviadilo-komponento por simple reteni ĉiun kromĉaron malpeza. Ofte en servaj maŝsolvoj, la kontrolaviadilo distribuas servo-eltrovinformojn al ĉiu kromĉaro. Kune kun ĝi venas informoj pri tempoforpasoj kaj ekvilibraj agordoj. Ĉio ĉi permesas vin fari multajn utilajn aferojn, sed, bedaŭrinde, ĝi ŝvelas kromĉarojn laŭ grandeco.

Servo-malkovro

Netramesh - malpeza serva maŝo-solvo

Netramesh ne aldonas iujn ajn kromajn mekanismojn por servo-malkovro. La tuta trafiko estas travidebla travideble per netra sidecar.

Netramesh subtenas HTTP/1-aplikprotokolon. Por difini ĝin, agordebla listo de havenoj estas uzata. Tipe, la sistemo havas plurajn havenojn tra kiuj HTTP-komunikado okazas. Ekzemple, ni uzas 80, 8890, 8080 por interagado inter servoj kaj eksteraj petoj.En ĉi tiu kazo, ili povas esti agordi per mediovariablo. NETRA_HTTP_PORTS.

Se vi uzas Kubernetes kiel orkestranton kaj ĝian Servan entan mekanismon por intra-grupo komunikado inter servoj, tiam la mekanismo restas ekzakte la sama. Unue, la mikroservo akiras servon IP-adreson uzante kube-dns kaj malfermas novan konekton al ĝi. Tiu ĉi ligo unue estas establita kun la loka netra-sidecar kaj ĉiuj TCP-pakaĵetoj komence alvenas ĉe netra. Poste, netra-sidecar establas ligon kun la origina celloko. NAT sur pod IP sur la nodo restas ekzakte sama kiel sen netra.

Distribuita spurado kaj kunteksta plusendado

Netramesh provizas la funkciojn necesajn por sendi spurajn intervalojn pri HTTP-interagoj. Netra-sidecar analizas la HTTP-protokolon, mezuras petajn prokrastojn kaj ĉerpas la necesajn informojn el HTTP-kapoj. Finfine, ni ricevas ĉiujn spurojn en ununura Jaeger-sistemo. Por fajna agordo, vi ankaŭ povas uzi la mediajn variablojn provizitajn de la oficiala biblioteko jaeger go biblioteko.

Netramesh - malpeza serva maŝo-solvo

Netramesh - malpeza serva maŝo-solvo

Sed estas problemo. Ĝis servoj kreos kaj sendos specialan uber-kapon, ni ne vidos konektitajn spurajn intervalojn en la sistemo. Kaj ĉi tio estas kion ni bezonas por rapide trovi la kaŭzon de problemoj. Ĉi tie denove Netramesh havas solvon. Prokuriloj legas HTTP-kapojn kaj, se ili ne enhavas la uber-spuridentigilon, generas unu. Netramesh ankaŭ stokas informojn pri alvenantaj kaj eksiĝintaj petoj en kromĉaro kaj kongruas ilin riĉigante ilin per la necesaj eksiĝintaj petoj kaplinioj. Ĉio, kion vi devas fari en la servoj, estas sendi nur unu kaplinion X-Request-Id, kiu povas esti agordita uzante mediovariablon NETRA_HTTP_REQUEST_ID_HEADER_NAME. Por kontroli la grandecon de la kunteksto en Netramesh, vi povas agordi la sekvajn mediovariablojn: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS (la tempo por kiu la kunteksto estos konservita) kaj NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL (frekvenco de kunteksta purigado).

Ankaŭ eblas kombini plurajn vojojn en via sistemo markante ilin per speciala sesioĵetono. Netra permesas vin instali HTTP_HEADER_TAG_MAP por igi HTTP-kapojn en respondajn spurajn span-etikedojn. Ĉi tio povas esti speciale utila por testado. Post trapaso de la funkcia testo, vi povas vidi, kiu parto de la sistemo estis tuŝita per filtrado per la responda sesioŝlosilo.

Determini la Peton-Fonton

Por determini de kie venis la peto, vi povas uzi la funkcion aŭtomate aldoni kaplinion kun la fonto. Uzante mediovariablon NETRA_HTTP_X_SOURCE_HEADER_NAME Vi povas specifi kapnomon, kiu estos aŭtomate instalita. Uzante NETRA_HTTP_X_SOURCE_VALUE vi povas agordi la valoron al kiu la X-Fonto-kapo estos agordita por ĉiuj elirantaj petoj.

Ĉi tio permesas la distribuadon de ĉi tiu utila kaplinio esti distribuita unuforme tra la reto. Tiam vi povas uzi ĝin en servoj kaj aldoni ĝin al protokoloj kaj metrikoj.

Trafikvojigo kaj Netramesh-internoj

Netramesh konsistas el du ĉefaj komponentoj. La unua, netra-init, fiksas retajn regulojn por kapti trafikon. Li uzas iptables redirektas regulojn kapti ĉion aŭ parton de la trafiko sur kromĉaro, kio estas la dua ĉefa komponento de Netramesh. Vi povas agordi kiuj havenoj devas esti kaptitaj por alvenantaj kaj elirantaj TCP-sesioj: INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS.

La ilo ankaŭ havas interesan funkcion - probableca enrutado. Se vi uzas Netramesh ekskluzive por kolekti spurajn intervalojn, tiam en produktadmedio vi povas ŝpari resursojn kaj ebligi probablan vojigon uzante variablojn. NETRA_INBOUND_PROBABILITY и NETRA_OUTBOUND_PROBABILITY (de 0 ĝis 1). La defaŭlta valoro estas 1 (ĉiu trafiko estas kaptita).

Post sukcesa interkapto, netra sidecar akceptas la novan konekton kaj uzas SO_ORIGINAL_DST opcio de ingo por akiri la originalan celon. Netra tiam malfermas novan konekton al la origina IP-adreso kaj establas dudirektan TCP-komunikadon inter la partioj, aŭskultante la tutan trafikon trapasantan. Se la haveno estas difinita kiel HTTP, Netra provas analizi kaj spuri ĝin. Se HTTP-analizo malsukcesas, Netra falas reen al TCP kaj travideble prokuras la bajtojn.

Konstruado de dependeca grafeo

Post ricevi grandan kvanton da spuraj informoj en Jaeger, mi volas ricevi kompletan grafeon de interagoj en la sistemo. Sed se via sistemo estas sufiĉe ŝarĝita kaj miliardoj da spuraj interspacoj akumuliĝas tage, aldoni ilin ne fariĝas tiel facila tasko. Estas oficiala maniero fari tion: spark-dependecoj. Tamen, necesos horoj por konstrui kompletan grafeon kaj devigos vin elŝuti la tutan datumaron de Jaeger dum la pasintaj XNUMX horoj.

Se vi uzas Elasticsearch por stoki spurajn intervalojn, vi povas uzi simpla Golang-utilo, kiu konstruos la saman grafeon en minutoj uzante la funkciojn kaj kapablojn de Elasticsearch.

Netramesh - malpeza serva maŝo-solvo

Kiel uzi Netramesh

Netra povas esti facile aldonita al iu ajn servo prizorganta ajnan orkestranton. Vi povas vidi ekzemplon tie.

Nuntempe, Netra ne havas la kapablon aŭtomate efektivigi kromĉarojn al servoj, sed ekzistas planoj por efektivigo.

La estonteco de Netramesh

La ĉefa celo Netramesh estas atingi minimumajn rimedkostojn kaj altan efikecon, disponigante bazajn kapablojn por observeblo kaj kontrolo de inter-serva komunikado.

En la estonteco, Netramesh subtenos aliajn aplikajn tavolprotokolojn krom HTTP. L7-vojigo estos disponebla en proksima estonteco.

Uzu Netramesh se vi renkontas similajn problemojn kaj skribu al ni kun demandoj kaj sugestoj.

fonto: www.habr.com

Aldoni komenton