Co víme o mikroslužbách

Ahoj! Jmenuji se Vadim Madison a vedu vývoj platformy Avito System. O tom, jak ve firmě přecházíme od monolitické architektury k mikroslužbě, bylo řečeno nejednou. Je čas podělit se o to, jak jsme transformovali naši infrastrukturu, abychom z mikroslužeb vytěžili maximum a neztratili se v nich. Jak nám zde pomáhá PaaS, jak jsme zjednodušili nasazení a zredukovali vytvoření mikroslužby na jedno kliknutí – čtěte dále. Ne vše, o čem píšu níže, je plně implementováno v Avitu, součástí toho je, jak vyvíjíme naši platformu.

(A na konci tohoto článku budu mluvit o možnosti dostat se na třídenní seminář od odborníka na architekturu mikroslužeb Chrise Richardsona).

Co víme o mikroslužbách

Jak jsme se dostali k mikroslužbám

Avito je jednou z největších inzercí na světě, denně zveřejňuje více než 15 milionů nových inzerátů. Náš backend přijímá více než 20 tisíc požadavků za sekundu. Nyní máme několik stovek mikroslužeb.

Architekturu mikroslužeb budujeme více než rok. Jak přesně - naši kolegové podrobně řekl v naší sekci na RIT++ 2017. Na CodeFest 2017 (viz видео), Sergey Orlov a Michail Prokopchuk podrobně vysvětlili, proč jsme vůbec potřebovali přechod na mikroslužby a jakou roli zde hrál Kubernetes. Nyní děláme vše pro to, abychom minimalizovali náklady na škálování, které jsou vlastní takové architektuře.

Zpočátku jsme nevytvářeli ekosystém, který by nám komplexně pomáhal v rozvoji a spouštění mikroslužeb. Prostě shromáždili chytrá open source řešení, spustili je doma a nabídli vývojáři, aby se s nimi vypořádal. V důsledku toho šel na tucet míst (dashboardy, interní služby), načež posílil svou touhu ořezat kód starým způsobem, v monolitu. Zelená barva na obrázcích níže ukazuje, co vývojář dělá tak či onak vlastníma rukama, žlutá barva označuje automatizaci.

Co víme o mikroslužbách

Nyní v nástroji PaaS CLI jeden tým vytvoří novou službu a dva další přidají novou databázi a nasadí ji na Stage.

Co víme o mikroslužbách

Jak překonat éru „fragmentace mikroslužeb“

S monolitickou architekturou byli vývojáři kvůli konzistenci změn v produktu nuceni zjistit, co se děje s jejich sousedy. Při práci na nové architektuře už na sobě kontexty služeb nezávisí.

Kromě toho, aby byla architektura mikroslužeb efektivní, je nutné zavést mnoho procesů, jmenovitě:

• protokolování;
• sledování požadavků (Jaeger);
• agregace chyb (Sentry);
• stavy, zprávy, události z Kubernetes (Event Stream Processing);
• závodní limit / jistič (můžete použít Hystrix);
• kontrola konektivity služeb (používáme Netramesh);
• monitorování (Grafana);
• montáž (TeamCity);
• komunikace a upozornění (Slack, email);
• sledování úkolů; (Jira)
• příprava dokumentace.

Abychom zajistili, že systém neztratí integritu a zůstane efektivní, když se zvětšuje, přehodnotili jsme organizaci mikroslužeb v Avitu.

Jak spravujeme mikroslužby

Avito pomáhá provádět jedinou „politiku strany“ mezi mnoha mikroslužbami:

  • rozdělení infrastruktury do vrstev;
  • koncept platformy jako služby (PaaS);
  • sledování všeho, co se děje s mikroslužbami.

Úrovně abstrakce infrastruktury zahrnují tři vrstvy. Jdeme shora dolů.

A. Top - servisní síťka. Nejprve jsme zkoušeli Istio, ale ukázalo se, že využívá příliš mnoho zdrojů, což je pro naše objemy příliš drahé. Proto hlavní inženýr v architektonickém týmu Alexander Lukjančenko vyvinul své vlastní řešení − Netramesh (dostupný v Open Source), který aktuálně používáme ve výrobě a který spotřebovává několikanásobně méně zdrojů než Istio (nedělá však vše, čím se Istio může pochlubit).
B. Střední - Kubernetes. Na něm nasazujeme a provozujeme mikroslužby.
C. Dno - holý kov. Nepoužíváme mraky a věci jako OpenStack, ale sedíme výhradně na holém kovu.

Všechny vrstvy jsou kombinované PaaS. A tato platforma se zase skládá ze tří částí.

I. Generátory, spravované pomocí obslužného programu CLI. Právě ona pomáhá vývojáři vytvořit mikroslužbu správným způsobem a s minimálním úsilím.

II. Konsolidovaný kolektor s ovládáním všech přístrojů přes společnou palubní desku.

III. úložný prostor. Spojuje se s plánovači, které automaticky nastavují spouštěče pro smysluplné akce. Díky takovému systému neunikne ani jeden úkol jen proto, že někdo zapomněl dát úkol do Jiry. K tomu používáme interní nástroj s názvem Atlas.

Co víme o mikroslužbách

Implementace mikroslužeb v Avitu se také provádí podle jednotného schématu, což zjednodušuje kontrolu nad nimi v každé fázi vývoje a vydání.

Jak funguje standardní vývojový kanál mikroslužeb

Obecně řetězec vytváření mikroslužeb vypadá takto:

CLI-push → Průběžná integrace → Bake → Deploy → Umělé testy → Canary testy → Squeeze Testing → Výroba → Údržba.

Pojďme si to projít přesně v tomto pořadí.

CLI-push

• Vytvoření mikroslužby.
Dlouho jsme se snažili naučit každého vývojáře, jak dělat mikroslužby. Včetně napsaných podrobných pokynů v Confluence. Ale schémata se měnila a doplňovala. Výsledek – na začátku cesty se vytvořilo úzké hrdlo: spuštění mikroslužeb trvalo mnohem déle, než bylo povoleno, a přesto při jejich vytváření často docházelo k problémům.

Nakonec jsme vytvořili jednoduchý nástroj CLI, který automatizuje základní kroky pro vytvoření mikroslužby. Ve skutečnosti nahrazuje první git push. Tady je přesně to, co dělá.

- Vytvoří službu podle šablony - krok za krokem, v režimu "průvodce". Máme šablony pro hlavní programovací jazyky v backendu Avito: PHP, Golang a Python.

- Jeden příkaz po druhém nasazuje prostředí pro místní vývoj na konkrétním počítači - Minikube stoupá, grafy Helm se automaticky generují a spouštějí v místních kubernetes.

— Připojí požadovanou databázi. Vývojář nepotřebuje znát IP, přihlašovací jméno a heslo, aby získal přístup k databázi, kterou potřebuje - alespoň lokálně, alespoň ve Stage, alespoň ve výrobě. Databáze je navíc okamžitě nasazena v konfiguraci odolné proti chybám a s vyvážením.

- Provádí samočinnou montáž. Řekněme, že vývojář něco opravil v mikroslužbě prostřednictvím svého IDE. Utilita vidí změny v souborovém systému a na jejich základě znovu sestaví aplikaci (pro Golang) a restartuje se. U PHP jednoduše přepošleme adresář uvnitř krychle a tam se live-reload získá „automaticky“.

- Generuje autotesty. Ve formě přířezů, ale docela použitelné.

• Nasadit mikroslužbu.

Nasadit u nás mikroslužbu bývalo trochu ponuré. Povinné povinné:

I. Dockerfile.

II. Konfigurace
III. Helm-graf, který je sám o sobě těžkopádný a obsahuje:

- samotné grafy;
- šablony;
- specifické hodnoty zohledňující různá prostředí.

Zbavili jsme se bolesti z přepracování manifestů Kubernetes a nyní jsou automaticky generovány. Ale co je nejdůležitější, zjednodušili jsme nasazení na maximum. Od této chvíle máme soubor Dockerfile a vývojář zapisuje celou konfiguraci do jediného krátkého souboru app.toml.

Co víme o mikroslužbách

Ano, a v samotném app.toml je nyní záležitost na minutu. Předepisujeme, kde se má vytvořit kolik kopií služby (na dev-server, na staging, na produkci), označíme její závislosti. Všimněte si velikosti řádku = "small" v bloku [engine]. Toto je limit, který bude službě přidělen přes Kubernetes.

Dále se na základě konfigurace automaticky generují všechny potřebné Helmovy diagramy a vytváří se připojení k databázím.

• Základní validace. Tyto kontroly jsou také automatizované.
Je potřeba sledovat:
- existuje soubor Dockerfile;
- je tam app.toml;
- Existuje dokumentace?
— zda v pořadí závislosti;
— zda jsou nastavena pravidla varování.
K poslednímu bodu: majitel služby sám určuje, které metriky produktu má sledovat.

• Příprava dokumentace.
Stále problémová oblast. Zdá se, že je to nejzřetelnější, ale zároveň „často zapomenutý“ záznam, a tedy zranitelný článek řetězu.
Je nutné, aby dokumentace byla pro každou mikroslužbu. Zahrnuje následující bloky.

I. Stručný popis služby. Jen pár vět o tom, co dělá a k čemu slouží.

II. Odkaz na schéma architektury. Je důležité, aby bylo na první pohled snadno pochopitelné, zda například používáte Redis pro ukládání do mezipaměti nebo jako hlavní úložiště dat v trvalém režimu. V Avitu je to prozatím odkaz na Confluence.

III. runbook. Krátký průvodce spuštěním služby a jemnosti manipulace s ní.

IV. FAQ, kde by bylo dobré předvídat problémy, se kterými se mohou vaši kolegové při práci se službou setkat.

V. Popis koncových bodů API. Pokud náhle neuvedete destinace, kolegové, jejichž mikroslužby jsou propojeny s vašimi, na to téměř jistě doplatí. Nyní k tomu používáme Swagger a naše řešení nazvané brief.

VI. Štítky. Nebo značky, které ukazují, ke kterému produktu, funkčnosti, strukturálnímu členění společnosti služba patří. Pomáhají například rychle pochopit, zda právě používáte funkcionalitu, kterou vaši kolegové zavedli pro stejnou obchodní jednotku před týdnem.

VII. Majitel nebo majitelé služby. Ve většině případů je – nebo je – lze určit automaticky pomocí PaaS, ale u pojištění vyžadujeme, aby je vývojář specifikoval i ručně.

Nakonec je dobrou praxí provádět kontroly dokumentace, podobně jako kontroly kódu.

Kontinuální integrace

  • Příprava úložišť.
  • Vytvoření kanálu v TeamCity.
  • Udělení práv.
  • Vyhledejte vlastníky služeb. Zde je hybridní schéma - ruční značení a minimální automatizace z PaaS. Plně automatické schéma selže, když jsou služby převedeny na podporu jiného vývojového týmu nebo například když vývojář služby skončí.
  • Registrace služby v Atlasu (viz výše). Se všemi svými vlastníky a závislostmi.
  • Kontrola migrací. Kontrolujeme, zda mezi nimi nejsou nějaké potenciálně nebezpečné. V jednom z nich se například objeví alter tabulka nebo něco jiného, ​​co může narušit kompatibilitu datového schématu mezi různými verzemi služby. Poté se migrace neprovede, ale vloží do předplatného – PaaS by měla signalizovat vlastníkovi služby, kdy bude bezpečné ji použít.

Upéct

Další fází je balení služeb před nasazením.

  • Sestavení aplikace. Podle klasiky - v obrázku Docker.
  • Generování diagramů Helm pro samotnou službu a související zdroje. Včetně databází a mezipaměti. Jsou vytvářeny automaticky v souladu s konfigurací app.toml, která byla vygenerována ve fázi CLI-push.
  • Vytváření lístků pro administrátory k otevření portů (v případě potřeby).
  • Spouštění testů jednotek a výpočet pokrytí kódu. Pokud je pokrytí kódem pod zadanou prahovou hodnotou, pak s největší pravděpodobností služba nepůjde dále - k nasazení. Pokud je to na pokraji přijatelného, ​​bude službě přidělen „pesimizační“ koeficient: pokud v průběhu času nedojde ke zlepšení ukazatele, vývojář obdrží oznámení, že nedošlo k žádnému pokroku, pokud jde o testy ( a mělo by se s tím něco dělat).
  • Zohlednění omezení paměti a CPU. V podstatě píšeme mikroslužby v Golangu a provozujeme je v Kubernetes. Z toho plyne jedna jemnost spojená s funkcí jazyka Golang: ve výchozím nastavení se všechna jádra na počítači používají při spuštění, pokud explicitně nenastavíte proměnnou GOMAXPROCS, a když je na stejném počítači spuštěno několik takových služeb, začnou soutěžit o zdroje a vzájemně si zasahovat. Níže uvedené grafy ukazují, jak se mění doba provádění, pokud je aplikace spuštěna bez soupeření a v režimu závodu o zdroje. (Zdroje grafů jsou zde).

Co víme o mikroslužbách

Doba provedení, méně je lepší. Maximum: 643 ms, minimum: 42 ms. Na fotku se dá kliknout.

Co víme o mikroslužbách

Čas na operaci, méně je lepší. Maximum: 14091 ns, minimum: 151 ns. Na fotku se dá kliknout.

Ve fázi přípravy sestavy můžete tuto proměnnou nastavit explicitně nebo můžete použít knihovnu automaxprocs od kluků z Uberu.

Nasadit

• Kontrola konvencí. Než začnete dodávat sestavení služeb do zamýšlených prostředí, musíte zkontrolovat následující:
- Koncové body API.
— Korespondence odpovědí koncových bodů API se schématem.
- Formát protokolu.
- Nastavení hlaviček pro požadavky na službu (nyní to provádí netramesh)
- Nastavení značky vlastníka při odesílání zpráv na sběrnici (sběrnice událostí). To je nezbytné pro sledování konektivity služeb přes sběrnici. Na sběrnici můžete posílat jak idempotentní data, která nezvyšují konektivitu služeb (což je dobře), tak obchodní data, která zlepšují konektivitu služeb (což je velmi špatné!). A ve chvíli, kdy se tato konektivita stane problémem, pochopení toho, kdo sběrnici píše a čte, pomáhá správně oddělit služby.

Zatím v Avitu není moc konvencí, ale jejich fond se rozšiřuje. Čím více takových dohod ve formě, která je pro tým srozumitelná a pohodlná, tím snazší je udržovat konzistenci mezi mikroslužbami.

Syntetické testy

• Testování v uzavřené smyčce. K tomu nyní používáme open source hoverfly.io. Nejprve zaznamená skutečné zatížení služby a poté - pouze v uzavřené smyčce - emuluje.

• Zátěžové testování. Všechny služby se snažíme přivést k optimálnímu výkonu. A všechny verze každé služby by měly být podrobeny zátěžovému testování – abychom pochopili aktuální výkon služby a rozdíl oproti předchozím verzím stejné služby. Pokud po aktualizaci služby její výkon klesl jedenapůlkrát, je to pro její majitele jasný signál: musíte se v kódu ponořit a situaci napravit.
Vycházíme ze shromážděných dat, abychom například správně implementovali automatické škálování a nakonec abychom obecně pochopili, jak je služba škálovatelná.

Při zátěžovém testování kontrolujeme, zda spotřeba zdrojů odpovídá stanoveným limitům. A zaměřujeme se především na extrémy.

a) Podíváme se na celkové zatížení.
- Příliš malý - s největší pravděpodobností něco nefunguje vůbec, pokud zatížení náhle několikrát klesne.
- Příliš velké - nutná optimalizace.

b) Podívejte se na hranici RPS.
Zde se podíváme na rozdíl mezi aktuální verzí a předchozí a celkovým počtem. Pokud například služba vydá 100 rps, pak je buď špatně napsaná, nebo je to její specifikum, ale v každém případě je to důvod se na službu podívat velmi zblízka.
Pokud je naopak příliš mnoho RPS, pak možná nějaká chyba a některé koncové body přestaly provádět užitečné zatížení, ale jen některé return true;

Kanárské testy

Po absolvování syntetických testů provozujeme mikroslužbu na malém počtu uživatelů. Začínáme opatrně, s nepatrným podílem zamýšleného publika služby – méně než 0,1 %. V této fázi je velmi důležité, aby byly do monitoringu zadány správné technické a produktové metriky, aby co nejrychleji ukázaly problém ve službě. Minimální doba testu kanára je 5 minut, hlavní 2 hodiny. Pro komplexní služby nastavte čas v ručním režimu.
Analyzujeme:
- metriky specifické pro jazyk, zejména pracovníci php-fpm;
— chyby v Sentry;
— stavy odezvy;
— doba odezvy (doba odezvy), přesná a průměrná;
- latence;
- vyřízené a nevyřízené výjimky;
- metriky produktu.

Squeeze Testování

Squeeze Testing se také nazývá "squeeze" testování. Název techniky byl zaveden do Netflixu. Jeho podstatou je, že nejprve naplníme jednu instanci reálným provozem do stavu selhání a nastavíme tak její limit. Poté přidáme další instanci a načteme tento pár - opět na maximum; při prvním zmáčknutí vidíme jejich strop a deltu. A tak připojíme jednu instanci na krok a vypočítáme vzor ve změnách.
Data o testech prostřednictvím „ždímání“ plynou i do společné databáze metrik, kde jimi buď obohacujeme výsledky umělé zátěže, nebo jimi dokonce nahrazujeme „syntetiku“.

Výroba

• Měřítko. Zaváděním služby do výroby sledujeme, jak se škáluje. Sledování pouze indikátorů CPU je přitom podle našich zkušeností neefektivní. Automatické škálování s benchmarkingem RPS funguje ve své nejčistší podobě, ale pouze pro určité služby, jako je online streamování. Podíváme se tedy primárně na metriky produktu specifické pro aplikaci.

V důsledku toho při škálování analyzujeme:
- Indikátory CPU a RAM,
- počet požadavků ve frontě,
- Doba odezvy,
— prognóza založená na nashromážděných historických údajích.

Při škálování služby je také důležité sledovat její závislosti, aby se nestalo, že budeme škálovat první službu v řetězci a ty, ke kterým přistupuje, padnou pod zátěží. Abychom stanovili přijatelné zatížení pro celý fond služeb, podíváme se na historická data „nejbližší“ závislé služby (z hlediska CPU a RAM spolu s metrikami specifických pro aplikaci) a porovnáme je s historickými daty inicializaci služby a tak dále v celém „řetězci závislostí“ shora dolů.

Služby

Po zprovoznění mikroservisu na něj můžeme zavěsit triggery.

Zde jsou typické situace, ve kterých spouštěče fungují.
- Zjištěna potenciálně nebezpečná migrace.
- Byly vydány bezpečnostní aktualizace.
- Služba samotná nebyla dlouho aktualizována.
— Zatížení služby se znatelně snížilo nebo některé metriky jejích produktů jsou mimo normu.
— Služba již nesplňuje nové požadavky platformy.

Některé spouštěče jsou zodpovědné za stabilitu práce, některé - jako funkce údržby systému - například některá služba nebyla delší dobu nasazena a její základní image přestala procházet bezpečnostními kontrolami.

Přístrojová deska

Dashboard je zkrátka ovládací panel celého našeho PaaS.

  • Jediný informační bod o službě s údaji o jejím testovacím pokrytí, počtu jejích snímků, počtu produkčních kopií, verzích atd.
  • Nástroj pro filtrování dat podle služeb a štítků (tokeny příslušnosti k obchodním jednotkám, funkčnost produktu atd.)
  • Integrační nástroj s infrastrukturními nástroji pro sledování, protokolování a monitorování.
  • Jedno místo dokumentace pro služby.
  • Jediný úhel pohledu na všechny události podle služby.

Co víme o mikroslužbách
Co víme o mikroslužbách
Co víme o mikroslužbách
Co víme o mikroslužbách

Celkem

Před zavedením PaaS mohl nový vývojář strávit několik týdnů pochopením všech nástrojů potřebných ke spuštění mikroslužby v produkci: Kubernetes, Helm, naše interní funkce TeamCity, nastavení připojení k databázím a mezipaměti způsobem zabezpečeným proti selhání atd. Nyní trvá několik hodin přečíst si rychlý start a provést samotnou službu.

Udělal jsem zprávu na toto téma pro HighLoad ++ 2018, můžete vidět видео и představení.

Bonusová skladba pro ty, kteří dočetli až do konce

My v Avitu pořádáme interní třídenní školení pro vývojáře od Chris Richardson, odborník na architekturu mikroslužeb. Chceme dát možnost se na něm podílet některému ze čtenářů tohoto příspěvku. Zde program školení byl zveřejněn.

Školení se bude konat od 5. do 7. srpna v Moskvě. Jedná se o pracovní dny, které budou plně vytížené. Oběd a školení budou v naší kanceláři, cestu a ubytování si hradí vybraný účastník sám.

Můžete se přihlásit k účasti v tomto google formuláři. Od Vás - odpověď na otázku, proč je třeba se školení zúčastnit a informace, jak Vás kontaktovat. Odpovídejte anglicky, protože účastníka, který se dostane na školení, vybere sám Chris.
Jméno účastníka školení oznámíme aktualizací tohoto příspěvku a na sociálních sítích Avito pro vývojáře (AvitoTech v Фейсбуке, VKontakte, Twitter) nejpozději do 19. července.

Zdroj: www.habr.com

Přidat komentář