Wat weet ons van mikrodienste

Hallo! My naam is Vadim Madison, ek lei die ontwikkeling van die Avito-stelselplatform. Hoe ons in die maatskappy van 'n monolitiese argitektuur na 'n mikrodiens beweeg, is al meer as een keer gesê. Dit is tyd om te deel hoe ons ons infrastruktuur getransformeer het om die meeste uit mikrodienste te kry en nie daarin verlore te raak nie. Hoe PaaS ons hier help, hoe ons die ontplooiing vereenvoudig het en die skepping van 'n mikrodiens tot een klik verminder het - lees verder. Nie alles waaroor ek hieronder skryf, is volledig in Avito geïmplementeer nie, deel daarvan is hoe ons ons platform ontwikkel.

(En aan die einde van hierdie artikel sal ek praat oor die geleentheid om by 'n driedaagse seminaar uit te kom van 'n kenner in mikrodiensargitektuur, Chris Richardson).

Wat weet ons van mikrodienste

Hoe ons by mikrodienste uitgekom het

Avito is een van die grootste geklassifiseerde advertensies ter wêreld, dit publiseer meer as 15 miljoen nuwe advertensies per dag. Ons backend aanvaar meer as 20 duisend versoeke per sekonde. Nou het ons 'n paar honderd mikrodienste.

Ons bou al meer as 'n jaar 'n mikrodiensargitektuur. Hoe presies - ons kollegas in detail vertel by ons afdeling by RIT++ 2017. By CodeFest 2017 (sien video), Sergey Orlov en Mikhail Prokopchuk het breedvoerig verduidelik waarom ons enigsins die oorgang na mikrodienste benodig en watter rol Kubernetes hier gespeel het. Wel, nou doen ons alles om die skaalkoste wat inherent aan so 'n argitektuur is, te minimaliseer.

Aanvanklik het ons nie 'n ekosisteem geskep wat ons omvattend sou help met die ontwikkeling en bekendstelling van mikrodienste nie. Hulle het net slim oopbronoplossings versamel, dit tuis bekendgestel en die ontwikkelaar aangebied om dit te hanteer. As gevolg hiervan het hy na 'n dosyn plekke (dashboards, interne dienste) gegaan, waarna hy sy begeerte versterk het om die kode op die ou manier te sny, in 'n monoliet. Die groen kleur in die diagramme hieronder dui aan wat die ontwikkelaar op een of ander manier met sy eie hande doen, die geel kleur dui outomatisering aan.

Wat weet ons van mikrodienste

Nou, in die PaaS CLI-nut, skep een span 'n nuwe diens, en nog twee voeg 'n nuwe databasis by en ontplooi dit na Stage.

Wat weet ons van mikrodienste

Hoe om die era van "mikrodiensfragmentasie" te oorkom

Met 'n monolitiese argitektuur, ter wille van konsekwentheid van veranderinge in die produk, is ontwikkelaars gedwing om uit te vind wat met hul bure gebeur. Wanneer aan die nuwe argitektuur gewerk word, is dienskontekste nie meer van mekaar afhanklik nie.

Daarbenewens, vir die mikrodiensargitektuur om effektief te wees, is dit nodig om baie prosesse daar te stel, naamlik:

• aanteken;
• versoek opsporing (Jaeger);
• foutsamevoeging (Sentry);
• statusse, boodskappe, gebeure vanaf Kubernetes (gebeurtenisstroomverwerking);
• raslimiet / stroombreker (jy kan Hystrix gebruik);
• dienskonneksiebeheer (ons gebruik Netramesh);
• monitering (Grafana);
• samestelling (TeamCity);
• kommunikasie en kennisgewing (Slack, e-pos);
• taakopsporing; (Jira)
• voorbereiding van dokumentasie.

Om te verseker dat die stelsel nie integriteit verloor en doeltreffend bly soos dit skaal nie, het ons die organisasie van mikrodienste in Avito heroorweeg.

Hoe ons mikrodienste bestuur

Avito help om 'n enkele "partybeleid" uit te voer onder die vele mikrodienste:

  • verdeling van infrastruktuur in lae;
  • die konsep van Platform as 'n Diens (PaaS);
  • monitor alles wat met mikrodienste gebeur.

Die infrastruktuur-abstraksievlakke sluit drie lae in. Kom ons gaan van bo na onder.

A. Top - diensmaas. Ons het eers Istio probeer, maar dit het geblyk dat dit te veel hulpbronne gebruik, wat te duur is vir ons volumes. Daarom het die senior ingenieur in die argitektuurspan Alexander Lukyanchenko sy eie oplossing ontwikkel − Netramesh (beskikbaar in Open Source), wat ons tans in produksie gebruik en wat verskeie kere minder hulpbronne as Istio verbruik (maar nie alles doen waarmee Istio kan spog nie).
B. Medium - Kubernetes. Daarop ontplooi en bedryf ons mikrodienste.
C. Onderkant - kaal metaal. Ons gebruik nie wolke en dinge soos OpenStack nie, maar sit heeltemal op kaal metaal.

Alle lae is gekombineer PaaS. En hierdie platform bestaan ​​op sy beurt uit drie dele.

I. Kragopwekkers, bestuur deur die CLI-hulpprogram. Dit is sy wat die ontwikkelaar help om 'n mikrodiens op die regte manier en met 'n minimum moeite te skep.

II. Gekonsolideerde versamelaar met beheer van alle instrumente deur 'n gemeenskaplike dashboard.

III. berging. Verbind met skeduleers wat outomaties snellers stel vir betekenisvolle aksies. Danksy so 'n stelsel word nie 'n enkele taak gemis net omdat iemand vergeet het om 'n taak in Jira te plaas nie. Ons gebruik 'n interne hulpmiddel genaamd Atlas hiervoor.

Wat weet ons van mikrodienste

Die implementering van mikrodienste in Avito word ook volgens 'n enkele skema uitgevoer, wat beheer daaroor in elke stadium van ontwikkeling en vrystelling vergemaklik.

Hoe die standaard mikrodiens-ontwikkelingspyplyn werk

Oor die algemeen lyk die mikrodiensskeppingsketting soos volg:

CLI-stoot → Deurlopende integrasie → Bak → Ontplooi → Kunsmatige toetse → Kanarie-toetse → Druktoetsing → Produksie → Onderhoud.

Kom ons gaan dit presies in hierdie volgorde deur.

CLI-druk

• Die skep van 'n mikrodiens.
Ons het lank gesukkel om elke ontwikkelaar te leer hoe om mikrodienste te maak. Insluitend geskryf gedetailleerde instruksies in Confluence. Maar die skemas het verander en is aangevul. Die gevolg - 'n bottelnek is aan die begin van die reis gevorm: dit het baie meer tyd geneem om mikrodienste te begin as wat toegelaat is, en steeds was daar dikwels probleme met die skep daarvan.

Uiteindelik het ons 'n eenvoudige CLI-hulpmiddel gebou wat die basiese stappe vir die skep van 'n mikrodiens outomatiseer. Trouens, dit vervang die eerste git-stoot. Hier is presies wat sy doen.

- Skep 'n diens volgens 'n sjabloon - stap vir stap, in die "wizard"-modus. Ons het sjablone vir die hoofprogrammeertale in die Avito-agterkant: PHP, Golang en Python.

- Een opdrag op 'n slag ontplooi 'n omgewing vir plaaslike ontwikkeling op 'n spesifieke masjien - Minikube styg, Roerkaarte word outomaties gegenereer en in plaaslike kubernetes uitgevoer.

- Verbind die vereiste databasis. Die ontwikkelaar hoef nie die IP, login en wagwoord te ken om toegang te kry tot die databasis wat hy benodig nie - ten minste plaaslik, ten minste in Stage, ten minste in produksie. Boonop word die databasis onmiddellik in 'n foutverdraagsame opset en met balansering ontplooi.

- Dit voer self lewendige samestelling uit. Kom ons sê die ontwikkelaar het iets in die mikrodiens deur sy IDE reggestel. Die hulpprogram sien veranderinge in die lêerstelsel en herbou die toepassing (vir Golang) op grond daarvan en herbegin. Vir PHP stuur ons eenvoudig die gids binne die kubus aan en daar word die lewendige herlaai "outomaties" verkry.

- Genereer outotoetse. In die vorm van spasies, maar redelik bruikbaar.

• Ontplooi mikrodiens.

Dit was vroeër 'n bietjie somber om 'n mikrodiens by ons te ontplooi. Verpligtend vereis:

I. Dockerfile.

II. Config.
III. Roerkaart, wat op sigself omslagtig is en insluit:

- die kaarte self;
- sjablone;
- spesifieke waardes wat verskillende omgewings in ag neem.

Ons het die pyn uit die herverwerking van Kubernetes-manifeste geneem en nou word dit outomaties gegenereer. Maar die belangrikste is dat ons ontplooiing tot die uiterste vereenvoudig het. Van nou af het ons 'n Dockerfile, en die ontwikkelaar skryf die hele konfigurasie in 'n enkele kort app.toml-lêer.

Wat weet ons van mikrodienste

Ja, en in die app.toml self is daar nou 'n saak vir 'n minuut. Ons skryf voor waar hoeveel kopieë van die diens om in te samel (op die dev-bediener, op verhoog, op produksie), die afhanklikhede daarvan aandui. Let op die lyngrootte = "klein" in die [enjin]-blok. Dit is die limiet wat via Kubernetes aan die diens toegeken sal word.

Verder, op grond van die konfigurasie, word al die nodige Helm-kaarte outomaties gegenereer en verbindings met die databasisse geskep.

• Basiese validering. Sulke tjeks word ook geoutomatiseer.
Moet opspoor:
- is daar 'n Dockerfile;
- is daar app.toml;
- Is daar dokumentasie?
— hetsy in die volgorde van afhanklikheid;
— of waarskuwingsreëls opgestel is.
Tot die laaste punt: die eienaar van die diens spesifiseer self watter produkmaatstawwe om te monitor.

• Voorbereiding van dokumentasie.
Steeds 'n probleemarea. Dit blyk die mees voor die hand liggende, maar terselfdertyd die rekord "dikwels vergete" te wees, en dus die kwesbare skakel in die ketting.
Dit is nodig dat die dokumentasie vir elke mikrodiens is. Dit sluit die volgende blokke in.

I. Kort beskrywing van die diens. Net 'n paar sinne oor wat dit doen en waarvoor dit is.

II. Skakel na argitektuurdiagram. Dit is belangrik dat dit met 'n oogopslag maklik is om te verstaan, byvoorbeeld of jy Redis vir kas gebruik of as die hoofdatastoor in aanhoudende modus. In Avito, vir nou, is dit 'n skakel na Confluence.

III. runboek. 'n Kort gids vir die bekendstelling van die diens en die subtiliteite om dit te hanteer.

IV. Gereelde vrae, waar dit goed sal wees om probleme te verwag wat jou kollegas kan teëkom wanneer hulle met die diens werk.

V. Beskrywing van API eindpunte. As jy skielik nie bestemmings gespesifiseer het nie, sal kollegas wie se mikrodienste aan joune gekoppel is, byna seker daarvoor betaal. Nou gebruik ons ​​Swagger hiervoor en ons oplossing genoem kort.

VI. Etikette. Of merkers wat wys aan watter produk, funksionaliteit, strukturele afdeling van die maatskappy die diens behoort. Hulle help om byvoorbeeld vinnig te verstaan ​​of jy die funksionaliteit sien wat jou kollegas 'n week gelede vir dieselfde besigheidseenheid uitgerol het.

VII. Dienseienaar of eienaars. In die meeste gevalle kan dit - of hulle - outomaties bepaal word met behulp van PaaS, maar vir versekering vereis ons dat die ontwikkelaar dit ook met die hand spesifiseer.

Laastens is dit goeie praktyk om dokumentasie-oorsigte uit te voer, soortgelyk aan kode-oorsigte.

Deurlopende integrasie

  • Voorbereiding van bewaarplekke.
  • Skep 'n pyplyn in TeamCity.
  • Toekenning van regte.
  • Soek vir dienseienaars. Hier is 'n hibriede skema - handmatige merk en minimale outomatisering van PaaS. Die ten volle outomatiese skema misluk wanneer dienste oorgedra word na ondersteuning in 'n ander ontwikkelingspan of, byvoorbeeld, as die diensontwikkelaar ophou.
  • Diensregistrasie in Atlas (sien hierbo). Met al sy eienaars en afhanklikhede.
  • Kontroleer migrasies. Ons kyk of daar enige potensieel gevaarlike onder hulle is. Byvoorbeeld, in een van hulle verskyn 'n wysigingstabel of iets anders wat die versoenbaarheid van die dataskema tussen verskillende weergawes van die diens kan breek. Dan word die migrasie nie uitgevoer nie, maar in 'n intekening geplaas - PaaS moet die eienaar van die diens aandui wanneer dit veilig word om dit toe te pas.

Bak

Die volgende fase is verpakkingsdienste voor ontplooiing.

  • Toepassing samestelling. Volgens die klassieke - in 'n Docker-beeld.
  • Generering van Helm-kaarte vir die diens self en verwante hulpbronne. Insluitend vir databasisse en kas. Hulle word outomaties geskep in ooreenstemming met die app.toml-konfigurasie wat by die CLI-drukstadium gegenereer is.
  • Skep kaartjies vir admins om poorte oop te maak (wanneer nodig).
  • Voer eenheidstoetse uit en bereken kodedekking. As die kodedekking onder die gespesifiseerde drempelwaarde is, sal die diens waarskynlik nie verder gaan nie - na die ontplooiing. As dit op die rand van aanvaarbaar is, sal die diens 'n "pessimerende" koëffisiënt toegeken word: dan, as daar geen verbetering in die aanwyser met verloop van tyd is nie, sal die ontwikkelaar 'n kennisgewing ontvang dat daar geen vordering in terme van toetse is nie ( en iets moet daaromtrent gedoen word).
  • Verantwoording vir geheue en SVE beperkings. Basies skryf ons mikrodienste in Golang en bestuur dit in Kubernetes. Daarom, een subtiliteit wat verband hou met die kenmerk van die Golang-taal: by verstek word alle kerns op die masjien gebruik by opstart, as jy nie die GOMAXPROCS-veranderlike uitdruklik instel nie, en wanneer verskeie sulke dienste op dieselfde masjien geloods word, begin hulle om te kompeteer vir hulpbronne, wat met mekaar inmeng. Die grafieke hieronder wys hoe die uitvoeringstyd verander as die toepassing sonder twis en in hulpbronwedren-modus uitgevoer word. (Die bronne van die kaarte is hier).

Wat weet ons van mikrodienste

Uitvoering tyd, minder is beter. Maksimum: 643 ms, minimum: 42 ms. Foto is klikbaar.

Wat weet ons van mikrodienste

Tyd vir operasie, minder is beter. Maksimum: 14091 ns, minimum: 151 ns. Foto is klikbaar.

By die samestelling voorbereiding stadium kan jy hierdie veranderlike eksplisiet stel of jy kan die biblioteek gebruik automaxprocs van die ouens by Uber.

Ontplooi

• Kontroleer konvensies. Voordat jy begin om diensbou aan jou beoogde omgewings te lewer, moet jy die volgende nagaan:
- API eindpunte.
— Korrespondensie van API-eindpunte-antwoorde op die skema.
- Log formaat.
- Stel opskrifte vir versoeke na die diens op (dit word nou deur netramesh gedoen)
- Stel die eienaarmerker in wanneer boodskappe na die bus (gebeurtenisbus) gestuur word. Dit is nodig om die verbinding van dienste deur die bus na te spoor. Jy kan beide idempotente data na die bus stuur wat nie die konnektiwiteit van dienste verhoog nie (wat goed is), en besigheidsdata wat die konnektiwiteit van dienste verbeter (wat baie sleg is!). En op die oomblik wanneer hierdie konnektiwiteit 'n probleem word, help om te verstaan ​​wie die bus skryf en lees om die dienste behoorlik te skei.

Tot dusver is daar nie baie konvensies in Avito nie, maar hul swembad brei uit. Hoe meer sulke ooreenkomste in 'n vorm wat vir die span verstaanbaar en gerieflik is, hoe makliker is dit om konsekwentheid tussen mikrodienste te handhaaf.

Sintetiese toetse

• Geslote lustoetsing. Daarvoor gebruik ons ​​nou oopbron sweefvlieg.io. Eerstens teken dit die werklike las op die diens aan, dan - net in 'n geslote lus - dit naboots.

• Strestoetsing. Ons probeer om alle dienste tot optimale prestasie te bring. En alle weergawes van elke diens moet onderwerp word aan vragtoetsing - sodat ons die huidige prestasie van die diens en die verskil met vorige weergawes van dieselfde diens kan verstaan. As die prestasie na 'n diensopdatering met een en 'n half keer gedaal het, is dit 'n duidelike sein vir sy eienaars: jy moet in die kode delf en die situasie regstel.
Ons begin byvoorbeeld by die versamelde data om outomatiese skaal korrek te implementeer en om uiteindelik in die algemeen te verstaan ​​hoe skaalbaar die diens is.

Tydens vragtoetsing kyk ons ​​of hulpbronverbruik aan die gestelde limiete voldoen. En ons fokus hoofsaaklik op uiterstes.

a) Ons kyk na die totale vrag.
- Te klein - heel waarskynlik werk iets glad nie as die vrag skielik verskeie kere daal nie.
- Te groot - optimalisering vereis.

b) Kyk na die RPS-afsnypunt.
Hier kyk ons ​​na die verskil tussen die huidige weergawe en die vorige een en die totale getal. Byvoorbeeld, as die diens 100 rps gee, is dit óf swak geskryf, óf dit is die besonderhede daarvan, maar dit is in elk geval 'n rede om die diens baie noukeurig te bekyk.
As daar inteendeel te veel RPS is, dan is miskien 'n soort fout en sommige van die eindpunte het opgehou om die loonvrag uit te voer, maar net 'n paar return true;

Kanarie toetse

Nadat die sintetiese toetse geslaag is, loop ons die mikrodiens op 'n klein aantal gebruikers. Ons begin versigtig, met 'n klein deel van die beoogde gehoor van die diens - minder as 0,1%. Op hierdie stadium is dit baie belangrik dat die korrekte tegniese en produkmaatstawwe in die monitering ingevoer word sodat dit so vinnig moontlik die probleem in die diens wys. Die minimum kanarie toetstyd is 5 minute, die hoof een is 2 uur. Vir komplekse dienste stel ons die tyd in handmodus.
Ons ontleed:
- taalspesifieke maatstawwe, veral php-fpm-werkers;
— foute in Sentry;
— reaksiestatusse;
— reaksietyd (reaksietyd), presies en gemiddeld;
- latensie;
- uitsonderings, hanteer en onbehandeld;
- produk statistieke.

Druk toets

Squeeze-toetsing word ook "squeeze"-toetsing genoem. Die naam van die tegniek is in Netflix bekendgestel. Die essensie daarvan is dat ons eers een geval met werklike verkeer vul tot die toestand van mislukking en sodoende sy limiet stel. Dan voeg ons nog 'n instansie by en laai hierdie paartjie - weer tot die maksimum; ons sien hul plafon en delta met die eerste druk. En so verbind ons een geval per stap en bereken die patroon in die veranderinge.
Data oor toetse deur "squeezing" vloei ook in 'n algemene databasis van metrieke in, waar ons óf die resultate van kunsmatige lading daarmee verryk, óf selfs "sintetika" daarmee vervang.

Produksie

• Skaal. Met die uitrol van die diens na produksie, monitor ons hoe dit skaal. Terselfdertyd is dit volgens ons ervaring ondoeltreffend om slegs SVE-aanwysers te monitor. Outomatiese skaal met RPS-benchmarking werk in sy suiwerste vorm, maar net vir sekere dienste, soos aanlynstroming. Ons kyk dus hoofsaaklik na toepassingspesifieke produkmaatstawwe.

As gevolg hiervan, wanneer ons skaal, ontleed ons:
- SVE en RAM-aanwysers,
- die aantal versoeke in die tou,
- reaksie tyd,
- voorspelling gebaseer op opgehoopte historiese data.

Wanneer 'n diens skaal word, is dit ook belangrik om tred te hou met sy afhanklikhede sodat dit nie gebeur dat ons die eerste diens in die ketting skaal, en dié waartoe dit toegang kry, onder las val nie. Om 'n aanvaarbare las vir die hele poel dienste daar te stel, kyk ons ​​na die historiese data van die "naaste" afhanklike diens (in terme van SVE en RAM, tesame met toepassingspesifieke maatstawwe) en vergelyk dit met die historiese data van die initialiseringsdiens, ensovoorts langs die hele “afhanklikheidsketting”, van bo na onder.

diens

Nadat die mikrodiens in werking gestel is, kan ons snellers daaraan hang.

Hier is tipiese situasies waarin snellers werk.
- Potensieel gevaarlike migrasies bespeur.
- Sekuriteitsopdaterings is vrygestel.
- Die diens self is lanklaas opgedateer.
— Die las op die diens het merkbaar afgeneem of sommige van sy produkmaatstawwe is buite die norm.
— Die diens voldoen nie meer aan die nuwe vereistes van die platform nie.

Sommige van die snellers is verantwoordelik vir die stabiliteit van die werk, sommige - as 'n stelselinstandhoudingsfunksie - byvoorbeeld, sommige diens is lanklaas ontplooi en sy basisbeeld het opgehou om sekuriteitskontroles te slaag.

Dashboard

Kortom, die paneelbord is die beheerpaneel van ons hele PaaS.

  • 'n Enkele punt van inligting oor die diens, met data oor die toetsdekking daarvan, die aantal beelde, die aantal produksie-kopieë, weergawes, ens.
  • 'n Hulpmiddel om data volgens dienste en etikette te filter (tekens van behoort aan besigheidseenhede, produkfunksionaliteit, ens.)
  • Integrasie-instrument met infrastruktuur-instrumente vir opsporing, aanteken, monitering.
  • Enkelpunt van dokumentasie vir dienste.
  • 'n Enkele oogpunt van alle gebeure deur diens.

Wat weet ons van mikrodienste
Wat weet ons van mikrodienste
Wat weet ons van mikrodienste
Wat weet ons van mikrodienste

In totaal

Voor die bekendstelling van PaaS, kan 'n nuwe ontwikkelaar etlike weke spandeer om al die gereedskap te verstaan ​​wat nodig is om 'n mikrodiens in produksie te begin: Kubernetes, Helm, ons interne TeamCity-kenmerke, die opstel van 'n verbinding met databasisse en kas op 'n foutverdraagsame manier, ens. Nou neem dit 'n paar uur om vinnig te begin lees en die diens self te maak.

Ek het 'n verslag oor hierdie onderwerp gemaak vir HighLoad ++ 2018, jy kan sien video и voorlegging.

Bonussnit vir diegene wat tot die einde lees

Ons in Avito organiseer 'n interne drie-dag opleiding vir ontwikkelaars van Chris Richardson, 'n kenner in mikrodiensargitektuur. Ons wil die geleentheid gee om daaraan deel te neem aan een van die lesers van hierdie berig. Hier die opleidingsprogram is geplaas.

Die opleiding word van 5 tot 7 Augustus in Moskou gehou. Dit is werksdae wat ten volle beset sal wees. Middagete en opleiding sal in ons kantoor wees, en die gekose deelnemer betaal self vir die reis en verblyf.

Jy kan aansoek doen om deel te neem in hierdie Google-vorm. Van jou - die antwoord op die vraag waarom jy die opleiding moet bywoon en inligting oor hoe om jou te kontak. Antwoord in Engels, want die deelnemer wat by die opleiding kom, sal deur Chris self gekies word.
Ons sal die naam van die opleidingsdeelnemer aankondig met 'n opdatering van hierdie pos en op sosiale netwerke Avito vir ontwikkelaars (AvitoTech in Фейсбуке, Vkontakte, Twitter) nie later nie as 19 Julie.

Bron: will.com

Voeg 'n opmerking