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.
Mi delonge serĉas ilon, kiu helpus trakti tiajn problemojn (mi skribis pri tio ĉe Habré:
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.
Solvoj
Jam ekzistas pluraj efektivigoj de ĉi tiu aliro:
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
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.
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:
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:
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 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
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 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:
Se vi uzas Elasticsearch por stoki spurajn intervalojn, vi povas uzi
Kiel uzi Netramesh
Netra povas esti facile aldonita al iu ajn servo prizorganta ajnan orkestranton. Vi povas vidi ekzemplon
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
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