Čo vieme o mikroslužbách

Ahoj! Volám sa Vadim Madison a vediem vývoj platformy Avito System. Už viac ako raz bolo povedané, ako vo firme prechádzame od monolitickej architektúry k mikroslužbám. Je čas podeliť sa o to, ako sme transformovali našu infraštruktúru, aby sme z mikroslužieb vyťažili maximum a zabránili tomu, aby sme sa v nich stratili. Ako nám tu pomáha PaaS, ako sme zjednodušili nasadenie a zredukovali vytvorenie mikroslužby na jedno kliknutie – čítajte ďalej. Nie všetko, o čom píšem nižšie, je plne implementované v Avite, niektoré z nich vyvíjame na našej platforme.

(A na konci tohto článku budem hovoriť o príležitosti zúčastniť sa trojdňového seminára od odborníka na architektúru mikroslužieb Chrisa Richardsona).

Čo vieme o mikroslužbách

Ako sme sa dostali k mikroslužbám

Avito je jednou z najväčších klasifikovaných stránok na svete, denne sa na nej zverejní viac ako 15 miliónov nových inzerátov. Náš backend prijíma viac ako 20 tisíc požiadaviek za sekundu. V súčasnosti máme niekoľko stoviek mikroslužieb.

Architektúru mikroslužieb budujeme už niekoľko rokov. Ako presne - naši kolegovia podrobne povedal v našej sekcii na RIT++ 2017. Na CodeFeste 2017 (viď. video), Sergey Orlov a Michail Prokopchuk podrobne vysvetlili, prečo potrebujeme prechod na mikroslužby a akú úlohu tu zohral Kubernetes. Teraz robíme všetko preto, aby sme minimalizovali náklady na škálovanie, ktoré sú vlastné takejto architektúre.

Spočiatku sme nevytvorili ekosystém, ktorý by nám komplexne pomáhal rozvíjať a spúšťať mikroslužby. Jednoducho zhromaždili rozumné open source riešenia, spustili ich doma a pozvali vývojára, aby sa s nimi zaoberal. V dôsledku toho šiel na tucet miest (dashboardy, interné služby), po ktorých sa posilnil v túžbe orezať kód starým spôsobom, v monolite. Zelená farba v nižšie uvedených diagramoch označuje, čo vývojár robí tak či onak vlastnými rukami, a žltá farba označuje automatizáciu.

Čo vieme o mikroslužbách

Teraz v nástroji PaaS CLI sa vytvorí nová služba jedným príkazom a pridá sa nová databáza s ďalšími dvoma a nasadí sa do Stage.

Čo vieme o mikroslužbách

Ako prekonať éru „fragmentácie mikroslužieb“

S monolitickou architektúrou, kvôli konzistentnosti zmien v produkte, boli vývojári nútení zistiť, čo sa deje s ich susedmi. Pri práci na novej architektúre už kontexty služieb na sebe nezávisia.

Okrem toho, aby bola architektúra mikroslužieb efektívna, je potrebné vytvoriť mnoho procesov, konkrétne:

• ťažba dreva;
• sledovanie žiadosti (Jaeger);
• agregácia chýb (Sentry);
• stavy, správy, udalosti z Kubernetes (Event Stream Processing);
• pretekársky limit / istič (môžete použiť Hystrix);
• kontrola konektivity služieb (používame Netramesh);
• monitorovanie (Grafana);
• montáž (TeamCity);
• komunikácia a notifikácia (Slack, email);
• sledovanie úloh; (Jira)
• príprava dokumentácie.

Aby sme zabezpečili, že systém nestratí svoju integritu a zostane efektívny aj pri rozširovaní, prehodnotili sme organizáciu mikroslužieb v Avite.

Ako spravujeme mikroslužby

Nasledujúce informácie pomáhajú implementovať jednotnú „politiku strany“ medzi mnohými mikroslužbami Avito:

  • rozdelenie infraštruktúry na vrstvy;
  • koncept platformy ako služby (PaaS);
  • sledovanie všetkého, čo sa deje s mikroslužbami.

Vrstvy abstrakcie infraštruktúry zahŕňajú tri vrstvy. Poďme zhora nadol.

A. Horná - servisná sieťka. Najprv sme skúšali Istio, ale ukázalo sa, že využíva príliš veľa zdrojov, čo je príliš drahé pre naše objemy. Preto hlavný inžinier v architektonickom tíme Alexander Lukyanchenko vyvinul svoje vlastné riešenie - Netramesh (dostupný v Open Source), ktorý momentálne používame vo výrobe a ktorý spotrebuje niekoľkonásobne menej zdrojov ako Istio (nerobí však všetko, čím sa Istio môže pochváliť).
B. Stredná - Kubernetes. Nasadzujeme a prevádzkujeme na ňom mikroslužby.
C. Dno - holý kov. Nepoužívame mraky ani veci ako OpenStack, ale spoliehame sa výlučne na holý kov.

Všetky vrstvy sú spojené pomocou PaaS. A táto platforma sa zase skladá z troch častí.

I. Generátory, ovládaný cez obslužný program CLI. Práve ona pomáha vývojárovi vytvárať mikroslužbu správnym spôsobom a s minimálnym úsilím.

II. Konsolidovaný kolektor s ovládaním všetkých nástrojov cez spoločnú palubnú dosku.

III. Skladovanie. Spája sa s plánovačmi, ktoré automaticky nastavujú spúšťače pre významné akcie. Vďaka takémuto systému nezmeškáte ani jednu úlohu len preto, že niekto zabudol nastaviť úlohu v Jire. Používame na to interný nástroj s názvom Atlas.

Čo vieme o mikroslužbách

Implementácia mikroslužieb v Avito sa tiež vykonáva podľa jednotnej schémy, ktorá zjednodušuje kontrolu nad nimi v každej fáze vývoja a vydania.

Ako funguje štandardný vývojový kanál mikroslužieb?

Vo všeobecnosti reťazec vytvárania mikroslužieb vyzerá takto:

CLI-push → Priebežná integrácia → Pečenie → Nasadenie → Umelé testy → Canary testy → Testovanie stláčania → Výroba → Údržba.

Poďme si to prejsť presne v tomto poradí.

CLI-push

• Vytvorenie mikroslužby.
Dlho sme sa snažili naučiť každého vývojára robiť mikroslužby. To zahŕňalo písanie podrobných pokynov v Confluence. Ale schémy sa menili a dopĺňali. Výsledkom je, že na začiatku cesty sa objavilo úzke miesto: spustenie mikroslužieb trvalo oveľa viac času a napriek tomu sa pri ich vytváraní často vyskytli problémy.

Nakoniec sme vytvorili jednoduchú CLI utilitu, ktorá automatizuje základné kroky pri vytváraní mikroslužby. V skutočnosti nahrádza prvý git push. Tu je to, čo presne robí.

— Vytvorí službu podľa šablóny — krok za krokom, v režime „sprievodcu“. Máme šablóny pre hlavné programovacie jazyky v backende Avito: PHP, Golang a Python.

- Jeden príkaz naraz nasadí prostredie pre lokálny vývoj na konkrétnom stroji - Minikube sa spustí, Helm diagramy sa automaticky vygenerujú a spustia v lokálnom kubernetes.

— Pripojí požadovanú databázu. Vývojár nepotrebuje poznať IP, prihlasovacie meno a heslo, aby získal prístup k databáze, ktorú potrebuje – či už je to lokálne, vo fáze alebo vo výrobe. Okrem toho je databáza nasadená okamžite v konfigurácii odolnej voči chybám a s vyvážením.

— Vykonáva samo montáž pod napätím. Povedzme, že vývojár opravil niečo v mikroslužbe prostredníctvom svojho IDE. Pomôcka vidí zmeny v súborovom systéme a na základe nich znova zostaví aplikáciu (pre Golang) a reštartuje sa. V prípade PHP jednoducho prepošleme adresár vnútri kocky a tam sa „automaticky“ získa live-reload.

— Generuje autotesty. Vo forme polotovarov, ale celkom vhodné na použitie.

• Nasadenie mikroslužieb.

Nasadenie mikroslužby bola pre nás trochu fuška. Vyžadovalo sa nasledovné:

I. Dockerfile.

II. Konfig.
III. Tabuľka kormidla, ktorá je sama o sebe ťažkopádna a obsahuje:

— samotné mapy;
— šablóny;
— špecifické hodnoty zohľadňujúce rôzne prostredia.

Zbavili sme sa bolesti pri prepracovaní manifestov Kubernetes, takže sa teraz generujú automaticky. Ale čo je najdôležitejšie, zjednodušili nasadenie na doraz. Odteraz máme súbor Dockerfile a vývojár zapíše celú konfiguráciu do jedného krátkeho súboru app.toml.

Čo vieme o mikroslužbách

Áno, a v samotnom app.toml nie je na minútu čo robiť. Špecifikujeme, kde a koľko kópií služby sa má vytvoriť (na serveri pre vývojárov, pri príprave, vo výrobe) a uvádzame jej závislosti. Všimnite si veľkosť riadku = "small" v bloku [engine]. Toto je limit, ktorý bude pridelený službe cez Kubernetes.

Potom sa na základe konfigurácie automaticky vygenerujú všetky potrebné Helm diagramy a vytvoria sa pripojenia k databázam.

• Základná validácia. Takéto kontroly sú tiež automatizované.
Treba sledovať:
— existuje súbor Dockerfile;
— je tam app.toml;
— je k dispozícii dokumentácia?
— je závislosť v poriadku?
— či boli stanovené pravidlá varovania.
K poslednému bodu: majiteľ služby sám určuje, ktoré metriky produktu bude sledovať.

• Príprava dokumentácie.
Stále problémová oblasť. Zdá sa, že je to najočividnejšie, no zároveň je to aj „často zabudnutý“ záznam, a teda zraniteľný článok reťaze.
Je potrebné, aby ku každej mikroslužbe existovala dokumentácia. Zahŕňa nasledujúce bloky.

I. Stručný popis služby. Doslova pár viet o tom, čo robí a prečo je to potrebné.

II. Odkaz na schému architektúry. Je dôležité, že pri rýchlom pohľade naň je ľahké pochopiť, či napríklad používate Redis na ukladanie do vyrovnávacej pamäte alebo ako hlavné úložisko údajov v trvalom režime. V Avito je to zatiaľ odkaz na Confluence.

III. Runbook. Krátky návod na spustenie služby a zložitosť manipulácie s ňou.

IV. FAQ, kde by bolo dobré predvídať problémy, s ktorými sa vaši kolegovia môžu stretnúť pri práci so službou.

V. Popis koncových bodov pre API. Ak ste zrazu neuviedli destinácie, kolegovia, ktorých mikroslužby súvisia s vašimi, na to takmer určite doplatia. Teraz na to používame Swagger a naše riešenie s názvom brief.

VI. Štítky. Alebo značky, ktoré ukazujú, do ktorého produktu, funkčnosti alebo štrukturálnej divízie spoločnosti služba patrí. Pomôžu vám rýchlo pochopiť, či napríklad znižujete funkčnosť, ktorú vaši kolegovia zaviedli pre rovnakú obchodnú jednotku pred týždňom.

VII. Vlastník alebo vlastníci služby. Vo väčšine prípadov sa dá – alebo ich – určiť automaticky pomocou PaaS, ale pre istotu vyžadujeme, aby ich vývojár špecifikoval manuálne.

Nakoniec je dobrou praxou kontrolovať dokumentáciu, podobne ako pri kontrole kódu.

Kontinuálna integrácia

  • Príprava úložísk.
  • Vytvorenie kanála v TeamCity.
  • Nastavenie práv.
  • Vyhľadajte vlastníkov služieb. Existuje tu hybridná schéma - manuálne označovanie a minimálna automatizácia z PaaS. Plne automatická schéma zlyhá, keď sa služby prenesú na podporu inému vývojovému tímu alebo napríklad, ak vývojár služby skončí.
  • Registrácia služby v Atlase (viď vyššie). So všetkými jeho vlastníkmi a závislosťami.
  • Kontrola migrácií. Kontrolujeme, či niektorý z nich nie je potenciálne nebezpečný. Napríklad v jednej z nich sa objaví alter tabuľka alebo niečo iné, čo môže narušiť kompatibilitu dátovej schémy medzi rôznymi verziami služby. Potom sa migrácia nevykoná, ale umiestni do predplatného - PaaS musí signalizovať vlastníkovi služby, kedy je bezpečné ju použiť.

upiecť

Ďalšou fázou sú služby balenia pred nasadením.

  • Vytváranie aplikácie. Podľa klasiky - v obraze Docker.
  • Generovanie Helm diagramov pre samotnú službu a súvisiace zdroje. Vrátane databáz a vyrovnávacej pamäte. Vytvárajú sa automaticky v súlade s konfiguráciou app.toml, ktorá bola vygenerovaná vo fáze CLI-push.
  • Vytváranie lístkov pre správcov na otváranie portov (v prípade potreby).
  • Spustenie testov jednotiek a výpočet pokrytia kódu. Ak je pokrytie kódom pod stanovenou hranicou, potom s najväčšou pravdepodobnosťou služba nepôjde ďalej - k nasadeniu. Ak je to na hranici prijateľnosti, službe bude pridelený „pesimizujúci“ koeficient: ak v priebehu času nedôjde k zlepšeniu ukazovateľa, vývojár dostane upozornenie, že v testoch nedošlo k žiadnemu pokroku ( a treba s tým niečo robiť).
  • Zohľadňujúc obmedzenia pamäte a procesora. Mikroslužby píšeme hlavne v Golangu a spúšťame ich v Kubernetes. Z toho vyplýva jedna jemnosť spojená so zvláštnosťou jazyka Golang: v predvolenom nastavení sa pri spustení použijú všetky jadrá na počítači, ak explicitne nenastavíte premennú GOMAXPROCS, a keď sa na tom istom počítači spustí niekoľko takýchto služieb, spustia sa. súťažiť o zdroje a navzájom si zasahovať. Nižšie uvedené grafy ukazujú, ako sa zmení čas vykonania, ak spustíte aplikáciu bez sporu a v režime pretekov o zdroje. (Zdroje grafov sú tu).

Čo vieme o mikroslužbách

Čas realizácie, menej je lepšie. Maximum: 643 ms, minimum: 42 ms. Na fotku sa dá kliknúť.

Čo vieme o mikroslužbách

Čas na operáciu, menej je lepšie. Maximum: 14091 ns, minimum: 151 ns. Na fotku sa dá kliknúť.

Vo fáze prípravy zostavy môžete túto premennú nastaviť explicitne alebo môžete použiť knižnicu automaxprocs od chalanov z Uberu.

Nasadiť

• Kontrola konvencií. Skôr než začnete dodávať servisné zostavy do zamýšľaných prostredí, musíte skontrolovať nasledujúce:
- Koncové body API.
— Súlad odpovedí koncových bodov API so schémou.
— Formát denníka.
— Nastavenie hlavičiek pre požiadavky na službu (v súčasnosti to robí netramesh)
— Nastavenie tokenu vlastníka pri odosielaní správ na zbernicu udalostí. Je to potrebné na sledovanie konektivity služieb cez autobus. Do zbernice môžete posielať idempotentné dáta, ktoré nezvyšujú konektivitu služieb (čo je dobré), ako aj obchodné dáta, ktoré posilňujú konektivitu služieb (čo je veľmi zlé!). A v okamihu, keď sa táto konektivita stane problémom, pochopenie toho, kto píše a číta zbernicu, pomáha správne oddeliť služby.

V Avite zatiaľ nie je veľa konvencií, ale ich fond sa rozširuje. Čím viac takýchto dohôd je k dispozícii vo forme, ktorej tím môže rozumieť a rozumieť jej, tým ľahšie je udržiavať konzistentnosť medzi mikroslužbami.

Syntetické testy

• Testovanie v uzavretej slučke. Na to teraz používame open source Hoverfly.io. Najprv zaznamená skutočnú záťaž služby, potom ju – len v uzavretej slučke – emuluje.

• Záťažové testovanie. Všetky služby sa snažíme priviesť k optimálnemu výkonu. A všetky verzie každej služby musia byť podrobené záťažovému testovaniu – takto môžeme pochopiť aktuálny výkon služby a rozdiel oproti predchádzajúcim verziám tej istej služby. Ak po aktualizácii služby jeho výkon klesol jedenapolkrát, je to pre jeho majiteľov jasný signál: musíte sa pohrabať v kóde a situáciu napraviť.
Zozbierané údaje používame napríklad na správnu implementáciu automatického škálovania a v konečnom dôsledku na to, aby sme vo všeobecnosti pochopili, aká je služba škálovateľná.

Počas záťažového testovania kontrolujeme, či spotreba zdrojov spĺňa stanovené limity. A zameriavame sa predovšetkým na extrémy.

a) Pozeráme sa na celkové zaťaženie.
- Príliš malý - s najväčšou pravdepodobnosťou niečo vôbec nefunguje, ak zaťaženie náhle niekoľkokrát klesne.
- Príliš veľké - vyžaduje sa optimalizácia.

b) Pozeráme sa na cutoff podľa RPS.
Tu sa pozrieme na rozdiel medzi aktuálnou verziou a predchádzajúcou a celkovým množstvom. Napríklad, ak služba produkuje 100 rps, potom je buď zle napísaná, alebo je to jej špecifikum, ale v každom prípade je to dôvod pozrieť sa na službu veľmi pozorne.
Ak je naopak priveľa RPS, možno je tam nejaká chyba a niektoré koncové body prestali vykonávať užitočné zaťaženie a jednoducho sa spustí iný return true;

Kanárske testy

Po absolvovaní syntetických testov testujeme mikroslužbu na malom počte používateľov. Začíname opatrne, s malým podielom zamýšľaného publika služby – menej ako 0,1 %. V tejto fáze je veľmi dôležité, aby boli do monitoringu zahrnuté správne technické a produktové metriky, aby čo najrýchlejšie ukázali problém v službe. Minimálny čas na test kanárika je 5 minút, hlavný je 2 hodiny. Pri komplexných službách nastavujeme čas manuálne.
Poďme analyzovať:
— metriky špecifické pre daný jazyk, najmä pracovníci php-fpm;
— chyby v Sentry;
— stavy odozvy;
— čas odozvy, presný a priemerný;
— latencia;
— výnimky, spracované a nevybavené;
— metriky produktu.

Stláčacie testovanie

Testovanie stláčania sa tiež nazýva testovanie „stláčania“. Názov techniky bol zavedený do Netflixu. Jej podstatou je, že najskôr naplníme jednu inštanciu reálnou návštevnosťou až do zlyhania a tým nastavíme jej limit. Potom pridáme ďalšiu inštanciu a načítame túto dvojicu – opäť na maximum; pri prvom „stlačení“ vidíme ich strop a deltu. A tak spájame jednu inštanciu po druhej a vypočítavame vzor zmien.
Testovacie dáta prostredníctvom „stláčania“ prúdia aj do spoločnej databázy metrík, kde nimi buď obohacujeme výsledky umelého zaťaženia, alebo nimi dokonca nahrádzame „syntetiku“.

Výroba

• Zmena mierky. Keď zavádzame službu do výroby, sledujeme, ako sa mení. Podľa našich skúseností je sledovanie iba indikátorov CPU neúčinné. Automatické škálovanie s RPS benchmarkingom v jeho čistej forme funguje, ale len pre určité služby, ako je online streamovanie. Najprv sa teda pozrieme na metriky produktu špecifické pre aplikáciu.

Výsledkom je, že pri škálovaní analyzujeme:
- Indikátory CPU a RAM,
— počet žiadostí v rade,
- Doba odozvy,
— prognóza založená na nahromadených historických údajoch.

Pri škálovaní služby je tiež dôležité monitorovať jej závislosti, aby sme neškálovali prvú službu v reťazci a tie, ku ktorým pristupuje, zlyhali pri zaťažení. Na stanovenie prijateľného zaťaženia pre celý súbor služieb sa pozrieme na historické údaje „najbližšej“ závislej služby (na základe kombinácie indikátorov CPU a RAM v spojení s metrikami špecifickými pre aplikáciu) a porovnáme ich s historickými údajmi. inicializačnej služby a tak ďalej v rámci „reťazca závislostí“ zhora nadol.

služba

Po uvedení mikroservisu do prevádzky môžeme naň pripevniť spúšťače.

Tu sú typické situácie, v ktorých sa spúšťače vyskytujú.
— Zistené potenciálne nebezpečné migrácie.
— Boli vydané bezpečnostné aktualizácie.
— Samotná služba nebola dlho aktualizovaná.
— Zaťaženie služby sa výrazne znížilo alebo niektoré metriky jej produktu sú mimo normálneho rozsahu.
— Služba už nespĺňa požiadavky novej platformy.

Niektoré zo spúšťačov sú zodpovedné za stabilitu prevádzky, niektoré - ako funkcia údržby systému - napríklad niektorá služba nebola dlho nasadená a jej základný obraz prestal podliehať bezpečnostným kontrolám.

Dashboard

Dashboard je skrátka ovládací panel celého nášho PaaS.

  • Jediný informačný bod o službe s údajmi o jej testovacom pokrytí, počte jej obrázkov, počte produkčných kópií, verziách atď.
  • Nástroj na filtrovanie údajov podľa služieb a štítkov (značky príslušnosti k obchodným jednotkám, funkcionalita produktu atď.)
  • Nástroj na integráciu s nástrojmi infraštruktúry na sledovanie, protokolovanie a monitorovanie.
  • Jeden bod servisnej dokumentácie.
  • Jediný uhol pohľadu na všetky udalosti naprieč službami.

Čo vieme o mikroslužbách
Čo vieme o mikroslužbách
Čo vieme o mikroslužbách
Čo vieme o mikroslužbách

Celkom

Pred zavedením PaaS by nový vývojár mohol stráviť niekoľko týždňov pochopením všetkých nástrojov potrebných na spustenie mikroslužby v produkcii: Kubernetes, Helm, naše interné funkcie TeamCity, nastavenie pripojení k databázam a vyrovnávacej pamäte spôsobom odolným voči chybám atď. Prečítanie rýchleho spustenia a vytvorenie samotnej služby trvá niekoľko hodín.

Na túto tému som dal správu pre HighLoad++ 2018, môžete si ju pozrieť video и predstavenie.

Bonusová skladba pre tých, ktorí čítajú až do konca

My v Avito organizujeme interné trojdňové školenie pre vývojárov z r Chris Richardson, odborník na architektúru mikroslužieb. Chceli by sme dať možnosť zúčastniť sa na ňom jednému z čitateľov tohto príspevku. Tu Školiaci program bol zverejnený.

Školenie sa uskutoční od 5. do 7. augusta v Moskve. Ide o pracovné dni, ktoré budú plne vyťažené. Obed a školenie budú v našej kancelárii, cestu a ubytovanie si hradí vybraný účastník sám.

Môžete požiadať o účasť v tomto google formulári. Od Vás - odpoveď na otázku, prečo sa potrebujete zúčastniť školenia a informácie, ako Vás kontaktovať. Odpovedzte v angličtine, pretože Chris si sám vyberie účastníka, ktorý sa školenia zúčastní.
Meno účastníka školenia oznámime v aktualizácii tohto príspevku a na sociálnych sieťach Avito pre vývojárov (AvitoTech v facebook, VKontakte, cvrlikání) najneskôr do 19. júla.

Zdroj: hab.com

Pridať komentár