Hlavní navigace

Prechod hostingu na mikroslužby: cesta zlyhaní a úspechov

Lukáš Kasič

V šiestej časti seriálu sa pozrieme na cestu zlyhaní a úspechov pri adaptácii mikroslužieb v českej hostingovej spoločnosti. Ako česká hostingová spoločnosť rozbíja vlastné monolity a adaptuje mikroslužby.

Doba čtení: 18 minut

Sdílet

1. Zastavenie vývoja

IGNUM bude budúci rok bude sláviť svoje 20. narodeniny. Začínal ako poskytovateľ webhostingu a registrátor domén .CZ. Po niekoľkých rokoch sa vyvinul aj hlavný web www.domena.cz. Pôvodné rozhranie domény (stále dostupné a funkčné vďaka mikroslužbám na puvodni.domena.cz) je prevažne len webovým frontendom nad vlastným backendovým systémom IPASom.

Teraz sa vráťme v čase o 4 roky dozadu, do roku 2015.

IPAS je mohutný monolitický systém napísaný prevažne v C++, ktorý poháňa prakticky polovicu firmy. Stará sa o komunikáciu s piatimi registrami domén (CZ.NIC, SK-NIC, EUrid, Joker a Keysystems), obsahuje databázu doménových užívateľov, eviduje služby, objednávky, generuje doklady a podpisuje ich, obsahuje užívateľov, role zamestnancov a dokonca slúži ako ticketovací systém. Jeho kritičnosť bola podtrhnutá aj názvom serveru, na ktorom IPAS dlhé roky bežal – offline.core.ignum.cz.

Je zároveň nutné dodať, že tento systém nebolo možné škálovať ani ho nijako replikovať.

Aby toho nebolo málo, takéto monolity mal IGNUM od svojich počiatkov dva. IPAS riešil len „doménových“ zákazníkov, a ten druhý, monolit napísaný v PHP, mal na starosti hostingové služby (webhosting, mailhosting, serverhosting). Na vývoji týchto systémov sa vystriedali desiatky vývojárov, pričom každý z nich mal svoj vlastný spôsob uvažovania a svoje spôsoby vývoja softvéru.

Oba monolity fungovali takmer bezchybne a poskytovanie zavedených služieb bolo bez väčších problémov. A ak niečo funguje dobre, nie je dôvod na jeho prepis. Tou cenou avšak bol akýkoľvek vývoj.

Partner seriálu o mikroslužbách

V IGNUM mají rádi technologie a staví na nich vlastní mikroslužby, díky kterým je registrace a správa domén, hostingů a e-mailů pro zákazníky hračka. Vymýšlet jednoduchá řešení pro obsluhu složitých systémů a uvádět je v život je výzva. Společnost IGNUM miluje mikroslužby a je proto hrdým partnerem tohoto seriálu.

2. Jednoduché mikroslužby

Inšpirácia prišla z knihy biochémie a spôsobu, akým funguje komunikácia medzi tkanivami v ľudskom tele. Defakto každý orgán má svoju vymedzenú činnosť a pre zachovanie homeostázy a správnej funkcie tela nás evolúcia obdarila hormónmi. Jednotlivé orgány sa tak správajú ako mikroslužby a nimi vylúčené hormóny v krvi reprezentujú správy. Pohrávanie sa s týmito myšlienkami nás zaviedlo k tematike mikroslužieb, ktoré sme na internete míňali a v skutočnosti tak unikali našej pozornosti.

Prvé mikroslužby, ktoré sme vytvorili, boli jednoduché. Prastarú službu vizitiek (5MB statický hosting), ktorá mala vlastný server, sme chceli skonsolidovať a presunúť do nášho vlastného webhostingového clusteru LHC (Linux Hosting Cluster). Službu využívali len desiatky zákazníkov, a bolo to akceptovateľné riziko pre vyskúšanie niečoho nového.

Celú službu sme z hľadiska backendu reimplementovali. „eCardApi“ sa tak stala prvou mikroslužbou, ktorá nám relatívne rýchlo vyriešila technický problém s plným zachovaním biznis logiky. Logika pôvodnej služby bola naprogramovaná len vo frontende (v pôvodnej doméne) a mikroslužba nám tak umožnila časť kódu izolovať do nezávislého celku. Pritom šlo len o jednoduché REST API s vlastnou evidenciou, ktoré ďalej pracovalo so SOAP API pokročilejšieho clusteru. eCardApi a celá myšlienka vizitiek sa postupne transformovala do komplexnejšej šlužby „IGNUM Vizitka“, ktorá už je sama systémom pozostávajúcim z mikroslužieb.

Paralelne s eCardApi vzniklo „RedirApi“, ktoré rovnako reimplementovalo inú časť – webové a emailové presmerovanie domény (funkcia, ktorú je možné aktivovať v správe domén). V tej dobe sme už mali spustenú beta verziu súčasnej podoby webu www.domena.cz. Funkcionalitu presmerovania sme chceli mať konzistentnú aj na novej, aj na pôvodnej doméne a RedirApi je mikroslužbou, ktorá to umožňuje doteraz.

3. Interné konvencie, dilematy a zmena myslenia v programovaní

Mikroslužby sme programovali viac-menej na zelenej lúke, dosť sme experimentovali a urobili mnoho chýb. Najviac nás trápilo to, že sme nevedeli, čo je správne a čo nie. Doteraz neexistujú konvencie a best practices o tom, ako by sa mikroslužby mali tvoriť. Články Martina Fowlera a tutoriál o mikroslužbách od NGINXu boli užitočné a inšpiratívne. Na druhú stranu, stále nepopisovali všetky problémy nášho aplikačného systému navonok trpiaceho schizofréniou. Boli sme ochotní najať experta špecializujúceho sa na mikroslužby, ktorý by nám so zavádzaním mikroslužieb pomohol, avšak ani sme nevedeli, kde hľadať.

Interne sme si vytvorili BCP (best current practice) dokumenty, ktoré nám na začiatku výrazne pomohli pri tvorbe mikroslužieb. Ako jediné API pre nové služby využívame už len REST s JSON serializáciou. V súčasnosti asi najpoužívanejším „štandardom“ nielen u nás je JSON API (https://jsonapi.org). Nutne avšak neimplementujeme vždy všetku funkcionalitu.

Ďalšie užitočné princípy, ktorými sa riadime:

  • KISS (Keep it simple, stupid)
  • DRY (Don’t repeat yourself) – prevzaté z Django frameworku
  • SRP (Single responsibility principle) – filozofia UNIX utilít (sort, uniq, ls, cat…)

V počiatkoch sme sa snažili myslieť aj na budúcnosť a ako riešiť napríklad zmeny v API. Ak niektorý programátor zmení rozhranie, ako zabezpečiť spätnú kompatibilitu? Ideálnym riešením by bolo použiť knižnicu, ktorá by to celé riešila za nás – napríklad Protocol Buffers od Googlu. Princíp KISS nás vrátil späť na pevnú zem. Pre malý tím je to zbytočnosť – ak niečo také nastane, dohodneme sa, že všetky systémy využívajúce dané API upravíme. So zavedením CI to nerobilo žiadne ťažkosti.

Tu prichádza ďalšia zmena v myslení. Ak v nejakej aplikácii využívame API externej služby, samotná komunikácia s daným systémom by mala ísť len cez jednu proxy triedu, kde sa daná komunikácia implementuje. U nás žiaľ tento návrhový vzor nebol do tej doby samozrejmosťou.

4. Prvý kúsok monolitu

Mohutné príšery sa budú vždy brániť a nedovolia, aby ste im čokoľvek vzali. IPAS sa bránil a bráni sa doteraz. Avšak výzvy máme radi.

Jedným z problémov IPASu bolo to, že používal 3 nezávislé databázy. Jednu evidenčnú, druhú pre dokumenty a tretiu pre uchovávanie logov. Databázy dokumentov a logov boli (z nášho pohľadu) veľké a ročne vygenerovali stovky GB dát. A tie databázy boli na serveri pomenovanom po ovocí. Tú chybu nikdy neurobte, hlavne ak to ovocie zvykne zo stromu padať ako hruška.core.ignum.cz.

Databáza dokumentov bola kritická a akákoľvek práca nad akýmkoľvek dokumentom si vynútila kvôli svojej podstate vecí výlučný prístup. Do novej „IgnumDoc“ mikroslužby sme premigrovali takmer 1 TB dokumentov, ktoré boli pôvodne uložené v relačnej MS SQL databáze a IPAS sme naučili komunikovať s prvou mikroslužbou cez jednoduché REST API.

Tú istú mikroslužbu sme využili aj v iných systémoch, ktoré si držali vlastnú evidenciu dokumentov. IgnumDoc sme navrhli tak, aby umožňoval súbory ukladať do kolekcií (jedna kolekcia pre jednu aplikáciu), a zároveň vedel k jednotlivým súborom pridávať metadáta a na základe tých metadát vyhľadávať a získavať konkrétne súbory. Mikroslužba si drží interné ID súboru v rámci kolekcie, avšak ak klientska aplikácia toto ID nechce (alebo nemôže) využívať, môže namiesto toho využiť metadáta. Rollback v mikroslužbe, ak nastane chyba v monolite? Neriešime. Ten dokument bude z hľadiska externej služby nedostupný a „slepý“. A zopár slepých dokumentov nás netrápi.

Z hľadiska technológii využíva IgnumDoc pre ukladanie samotných dokumentov obyčajný Linuxový filesystém – žiadne relačné databázy, žiadne NoSQL. Interná databáza mikroslužby je MariaDB + TokuDB engine, a pre rýchlejšie vyhľadávanie v metadátach slúži ElasticSearch.

5. Socializácia monolitov a mikroslužieb

Mikroslužby sme spočiatku navrhovali tak, aby využívali klasické textové logy. Väčšia zmena prišla, keď sme chceli vidieť, čo sa v tých mikroslužbách realtimovo deje. Monolit môže všetky operácie logovať do jedného súboru, ale pustiť tail -f v piatich nezávislých konzolách, a realtimovo mergovať logy len očami dá zabrať.

Možné riešenie problému poskytoval ELK (ElasticSearch, Logstash, Kibana) stack. V tej dobe sme sa už začínali pohrávať s myšlienkou zavedenia Message Brokera. Aj preto sme Logstash nikdy neučili parsovať textové logy – od začiatku sme ho napojili na X exchandží rabbita, z ktorých všetky eventy boli smerované do jedného spoločného elastic indexu. Debugovanie a vyhľadávanie v logoch s pomocou Kibany všetko zjednodušilo.

Namiesto mechanického prepisovania volania loggeru v mikroslužbách sme implementovali posielanie správ. Uvedomili sme si, že vhodne štrukturované eventy môžu poslúžiť ako ekvivalent logov, len to chce jednotnú konvenciu.

{
    '@timestamp': '2019-06-10T03:47:33.121Z',
    '@type': 'ipas.telemetry.memory.usage',
    'data': {
        'allocated': '483MB'
    }
}
{
    "@timestamp": "2019-06-10T03:48:25.896Z",
    "@type": "ipas.session.created",
    "fields": {
      "is_ssl": false,
      "session_id": "FD0TQGTT6F",
      "client_ip": "62.109.128.170"
    }
} 
{
    "@timestamp": "2019-06-10T03:48:26.059Z",
    "@type": "ignumdoc.document.created",
    "id": 8346292,
    "fields": {
      "collection": "ipas.live",
      "filename": "invoice.pdf",
      "size": "1773"
    },
    "meta": {
      "link_type": 29,
      "link_id": 18736
    }
}
{
    "@timestamp": "2019-06-10T03:48:26.074Z",
    "@type": "ipas.command.finished",
    "fields": {
      "result": {
        "duration": 0,
        "description": "Command completed successfully.",
        "code": 0,
        "last_id": -1
      },
      "account_id": null,
      "user_id": 126968,
      "session_id": "FD0TQGTT6F",
      "params": {
        "AccountID": 97981
      },
      "cmdlog_id": "FD0TQGXB2P"
    }
}

Rýchlo sme zistili, že miešanie rôznych dátových typov ES nevonia a takéto logy od LogStashu štandardne neprijme (problém s  id, ktoré môže byť v jednej mikroslužbe integer, a v inej string). Zároveň ES nie je vhodným na dlhodobé uchovávanie logov (nami nastavená retencia sú 3 týždne). Pristúpili sme k odberu všetkých dát sadou skriptov, ktoré všetky eventy ukladajú do textových súborov podľa dňa a názvu aplikácie. Skripty sme taktiež naučili, aby do dlhodobého archívu ukladali len modifikujúce operácie. Debug eventy a eventy z operácii, ktoré len získavali dáta dlhodobo nepotrebujeme.

Pomocou Rabbita to šlo ľahko. Využili sme už skôr v tomto seriáli spomínaný publish/subscribe pattern. Kafka bola taktiež možnosťou, avšak prišla nám ako kanón na vrabce pre naše jednoduché use-casy.

Socializovali sme tak nielen mikroslužby, ale aj monolity. IPAS nebol moc flexibilný pre logovanie do súboru a analyzovať XML logy ukladané do MS SQL bolo nepraktické. Interný logovací mechanizmus IPASu sme celý reimplementovali a rozšírili. Pre bližšiu predstavu o tom, čo sa v tom monolite deje sme ďalším skriptom subscribli celý IPAS exchange a mnohé dáta sme začali ukladať do InfluxDB a zobrazovať graficky Grafanou.

Používanie Rabbita pre logovanie a ukladanie dokumentov do mikroslužby malo ešte jeden pozitívny prínos, ktorý spôsobil zmenu uvažovania. Nebolo potrebné naďalej používať persistentný storage. Mikroslužby tak boli pripravené na kontajnerizáciu. Niektoré mikroslužby pochopiteľne ten storage nutne potrebujú – avšak to sa vyrieši pripojením externého storagu (NFS, Ceph), a dokonca nič nebráni tomu, aby daná mikroslužba nebola na vlastnom fyzickom stroji. Ďalším krokom k bezdiskovému serveru a zjednodušenie vývoja a nasadzovania služieb je použitie systému pre ukladanie konfigurácie (consul, etcd), čím sa dostávame dokonca do stavu, kedy mikroslužbe pri spustení postačí connection string pre prístup ku vlastnej konfigurácii a aplikácia už vie, čo má robiť.

6. Problémy a pády

Jeden zo skriptov, ktorý zachytával všetky eventy a ukladal ich do textového logu, padol. Tieto skripty sme nastavili tak, aby používali „named durable queues“. To znamená, že v prípade pádu konzumera sa eventy sypú ďalej do fronty s konkrétnym menom a po pripojení konzumera si ich môže konzument z fronty vytiahnuť a spracovať. RabbitMQ funguje prevažne tak, že sa správy doručujú neustále – nerátali sme s tým, že sa tam začnú tie správy hromadiť. Správy, ktoré ostali visieť v durable fronte boli uložené len v pamäti RAM. A aj keď to bol RabbitMQ master-master cluster, virtuálne servery mali len 8GB RAM, čo je pre mikroslužby generujúce aj debug logy jedno veľké HAM.

Iróniou je, že sme monolity naučili, aby prežili pád rabbita. Ak je rabbit nedostupný, monolity ukladajú eventy do súboru. Po oživení rabbita sú mu všetky správy dodatočne zaslané. A keďže každý event obsahuje timestamp, kedy bol vytvorený, čas oneskorenia doručenia eventu nebol problémom.

Avšak mikroslužby sme spočiatku netvorili tak, aby boli odolné voči chybám rabbita alebo sieti. Až tak veľmi sme ich chceli mať jednoduché. Monitorovací systém hlásil pri kontrole API mikroslužieb Internal Server Error 500 a žiadne náznaky o problémoch. RabbitMQ v skutočnosti odmietal prijímať správy od producentov a tí sa z toho zrútili. Monolity tak žili svojim životom ďalej a kým nekomunikovali s mikroslužbami, tak bolo všetko v poriadku.

Zdroj problému bol jednoduchý, rovnako aj jeho riešenie. Zavedenie monitoringu využitia RAM na RabbitMQ serveroch (RAM štandardne nekontrolujeme – poučilo nás to, že s overcommit memory a vypnutým OOMK to je nutnosť). Ďalší nutný monitoring je kontrola, či sa neplní nejaká durable fronta bez konzumera. Spočiatku, kým sa neodchytali muchy občas nejaký skript padol, avšak to sa vyladilo a problémy s Rabbitom (aj keď on zato nemohol) sa úplne stratili.

Poznámka: Rabbit nás prekvapil ešte v jednej veci. Pri aktualizácii clusteru sa administrátorovi podarilo rozpojiť cluster, ktorý sa dostal do split-brain stavu, keď časť dát bola na vypadnutom serveri. Po obnove servera sa rabbit sám obnovil. Správy boli rabbitom prijímané, avšak ich doručovanie sa v čase výpadku pozastavilo. Vcelku dobre vymyslené správanie.

7. Komplexnejšie (distribuované) mikroslužby

Náš web www.domena.cz umožňuje rýchle vyhľadávanie voľných domén. Overenie dostupnosti domény je nutné riešiť cez register pre dané TLD. Toto overenie riešil pochopiteľne IPAS, keďže bol na všetky registre napojený.

Pri hromadnom overovaní dostupnosti domén sme bojovali s dvoma faktormi: registre majú obmedzený počet operácii a majú vlastné rate limity. Druhým faktorom je samotný IPAS a jeho výlučný prístup k registrom. V prípade KeySystems, cez ktorý registrujeme vyše 200 TLD to je pochopiteľne problém.

Štandardne sme všetky domény overovali voči registrom. Idea predtým nemysliteľná v prípade monolitu sa stala skutočnosťou – overovať voči registrom len tie domény, ktoré nemajú SOA záznam. Prvým „sitom“ je teda klasické DNS. Ak existujú DNS záznamy, tak doména je registrovaná a je zbytočné sa pýtať registrov.

Vo svete domén sa služba pre overovanie dostupnosti domény nazýva DAS – Domain Availability Service. Každý TLD register určitú formu DASu má. Modernejšie registre ako CZ.NIC, SK-NIC alebo EUrid ich poskytujú v rámci EPP protokolu, čo je štandardizovaný XML-based protokol pre komunikáciu s registrami domén. Zastaralé registre umožňujú overenie cez telnet na určitý port, alebo prostredníctvom klasického HTTP requestu.

Ak ste vstrebali základné princípy mikroslužieb, otvorí vám to oči pri návrhu nových systémov. Systém DAS, ktorý v súčasnosti využíva www.domena.cz pre rýchle vyhľadávanie domén je mikroslužbou zloženou z ďalších, už skôr nanoslužieb a workerov. Škálovateľný REST API frontend je napísaný vo flasku posielajúci správy do rabbitmq a využíva jednak nacachované dáta z REDISu. Backend DASu je dvojúrovňový – tvoria ho workeri, ktorí vykonávajú jednotlivé overenia dostupnosti domén.

Prvou úrovňou je overenie voči DNS, a ak je toto overenie nejednoznačné, prepadne overenie na druhú úroveň: overenie voči registru daného TLD. Správy sa ku správnym workerom dostanú pomocou routovania správ, ktoré zabezpečuje priamo RabbitMQ a podobnou cestou sa správy vracajú frontendu. V tejto architektúre sa backend dá veľmi jednoducho škálovať a rozširovať. Niektoré TLD je možné posilniť (alebo implementovať viacero workerov, napríklad cez whois a hodiť ich na desiatky IP adries) a exchange type „direct“ zabezpečí vhodné rozhadzovanie záťaže naprieč dostupnými workermi.

Samozrejme existujú špekulanti, ktorí by takýto systém radi zneužili. Keď sme využívali na overovanie domén ešte IPAS, tak sa jeden takýto špekulant aj našiel a dlho sme o ňom nevedeli. Monolit by nám avšak jednoducho neumožnil flexibilitu, ktorú nám mikroslužba môže poskytnúť. Rate limity per IP z pohľadu frontendu a dokonca per TLD z pohľadu backendu boli hračkou.

IPAS sme tak odľahčili o ďalšiu, veľkú časť operácii. Tým sa aj výrazne zrýchlili služby, ktoré boli stále poskytované týmto monolitom.

8. Prepojenie mikroslužieb so službami na serveroch

Ďalším komplexnejším systémom v IGNUM využívajúci princípy mikroslužieb je LHC/RBL. Systém realtimovo analyzuje telemetriu zasielaných IP adries z logov rôznych systémov a vyhodnocuje dôveryhodnosť IP adresy. Ak sa z jednej IP adresy, prípadne z celého /24 subnetu masívne spamuje, IP adrese klesá reputácia a môže byť následne systémom pridaná na interný mailový DNSBL. Podobne to môže byť v prípadoch, keď niekto začne útočiť na weby či už v zdieľanom hostingu, alebo aj na nami spravovaných manažovaných zákazníckych serveroch. Rovnako zbierame neúspešné pokusy o lámanie hesiel na SSH a mailové protokoly. Ide tak o jednoduchú realtime anti-DDoS ochranu z dát na aplikačnej L7 vrstve.

Tento systém sa nejaví ako mikroslužba. Mikroslužbami je len výrazne inšpirovaný. Ak má niečo jednu rolu a poskytuje to REST API, považujeme to v IGNUM viac-menej už za mikroslužbu. O to viac, ak daný systém emituje signály.

Skutočnou výhodou mikroslužieb je ich jednoduchosť. Mikroslužbu dokáže napísať aj junior programátor, alebo Linux administrátor, ktorý s programovaním ešte len začína.

Zostaňme ešte chvíľu na tejto úrovni. Ak provozujete distribuovaný LAMP alebo mailový cluster a sami ho vyvíjate, narazíte na problémy s distribúciou konfigurácie. Buď všetko napojíte na databázu, ktorú následne replikujete, alebo píšete skripty, ktoré sa spúšťajú cronom a generujú konfiguračné súbory s extrahovanými dátami z databázy. Ďalšou fázou je, keď máte aspoň čiastočne fungujúci systém mikroslužieb, ktoré posielajú správy message brokerovi, a z toho message brokera si serverové „worker“ skripty odoberajú správy, ktoré sa ich týkajú. Pridanie užívateľského SSH kľúča vo webovom clusteri pre prístup k webu u nás spôsobí emit správy ssh.key.created, ktorá je zaujímavá hlavne pre LHC SSH nody. Worker na serveroch upraví autorizované kľúče pre konkrétneho užívateľa prakticky okamžite. LHC servery bootujú z PXE a teda konfigurácia je dynamická. Pri spustení serveru sa tak všetka požadovaná konfigurácia inicializuje a pri spúšťaní sa kontaktujú požadované mikroslužby s požiadavkom na aktuálny stav konfigurácie.

Mikroslužby tak dokážu integrovať a zlepšiť spoluprácu nielen systémov a serverov, ale aj programátorov a administrátorov.

9. Delenie databáz, ACID, rollback

Jedným z najväčších problémov pri mikroslužbách je ich konzistencia. Detailnejšie bol tento problém spomínaný v druhej časti seriálu, kedy stav jednej mikroslužby je závislý od stavu dát v inej mikroslužbe. Takýmto závislostiam sa zatiaľ snažíme vyhýbať ako čert kríža a mikroslužby navrhujeme tak, aby tých závislostí bolo čo najmenej – preto to postupné oddeľovanie funkcionalít z monolitov.

Ak to dáva význam, nebojíme sa ani používaniu a tvorbe ďalších monolitov. Daný monolit avšak má byť rozumným kompromisom. Systém procesovania objednávok a billingu považujeme za tak komplikovaný a dôležitý, že možno nikdy nebude vo forme mikroslužieb. Jeho rozsekanie na

  • mikroslužbu pre kredit
  • mikroslužbu pre daňové doklady
  • mikroslužbu pre procesovanie objednávok
  • mikroslužbu pre evidenciu cien služieb

je z nášho pohľadu priveľmi zrnitá a náročná na realizáciu. Aspoň v súčasnej chvíli. Extrémne delenie databáz na menšie a menšie mikroslužby vedie k antipatternu zvanému nanoslužby, kedy existuje nanoslužba pre prakticky každú tabuľku a spravovať takýto systém bude podstatne náročnejšie, ako spravovať monolit.

Dokážeme žiť s tým, že budeme mať jeden väčší systém, ktorý bude riešiť objednávky, tvorbu daňových dokladov a zároveň umožní platbu kreditom. Je otázne, či pôjde o mikroslužbu, nakoľko poruší princíp jednej zodpovednosti, avšak tou jednou zodpovednosťou môže byť „objednávkový systém“. To, či vyfakturovanie a stiahnutie peňazí z kreditu patrí do objednávkového systému je na diskusiu. Takéto monolity nám avšak nevadia. Budú dostatočne malé, a ako sme sa už presvedčili, aj monolity môžu byť napojené na Rabbita a dáta mať prístupné cez REST API.

Nie vždy sa tomu avšak dá vyhnúť. Prípady, pri ktorých je určitá pravdepodobnosť, že niečo zlyhá alebo nedopadne dobre riešime zatiaľ dvoma spôsobmi.

Je samozrejme možné, že mikroslužba vygeneruje event, odošle ho, ale sama na ďalšom riadku padne. Čo majú urobiť systémy s takouto správou, ktoré už na jednotlivé eventy reagujú?

Ak správa obsahuje viac informácii, napr. že bola registrovaná doména (s platnosťou do XX), tak si cieľový konzument musí pochopiteľne overiť všetky potrebné informácie od „Source of truth“ (mikro)služby – ideálne získaním informácii cez API. Ak dôjde k neočakávanej chybe, ktorú systém nevie vyriešiť, konzumerská mikroslužba notifikuje nejakým kanálom chybu (Sentry, Slack, klasický mail) a je nutný manuálny zásah správcu systému pre analýzu toho, čo sa stalo a ako tomu predchádzať do budúcna.

Zatiaľ to nebolo zmieňované, ono to v kontexte mikroslužieb nie je moc potrebné, avšak monolity štandardne majú mnohokrát interné procesy a používajú nejaké crony. Kým sa dosiahne ideálny stav (každý s každým si posiela správy), aj mikroslužby by mali mať svoje interné procesy. Nočné interné procesy spúšťajú optimalizácie, avšak nič nelimituje ich rozšírenie aj na kontrolu integrity mikroslužby – či už internú, alebo externú. Rovnako ako bunky v ľudskom tele majú samoopravné mechanizmy, môžu ich mať aj mikroslužby.

10. DevOps, servisné služby

Rovnako ako monolity, aj mikroslužby vyžadujú určitú správu a servisné nástroje, ktoré pomôžu s identifikáciou problémov. Spočiatku sme mikroslužby monitorovali len klasickým Nagiosom a kontrolou HTTP kódu REST API. Výpadok jednej mikroslužby alebo jej časti spôsobil, že daná služba bola čiastočne, v horšom prípade úplne nefunkčná. Neskôr sme rozšírili API o /check  URL, ktorého zavolanie skontrolovalo, či sú všetky spojenia a všetky závislosti funkčné.

Súčasný prístup je rozšírený a niektoré mikroslužby mimo štandardnej fronty eventov emitujú aj heartbeat eventy a určité telemetrické dáta. Tu je možné využiť výhody pasívneho monitoringu, kedy absencia heartbeat eventu alebo telemetrických dát väčšinou poukazujú na problém. Ak to nežije, niečo je zle. Dashboardy nových, do produkcie zavedených mikroslužieb máme niekoľko dní až týždňov na očiach.

Niektoré mikroslužby (napríklad mikroslužba pre generovanie Let’s Encrypt certifikátov) majú vlastné webové rozhranie, ktoré umožňuje správcom a operátorom manuálne vykonať operácie. Pri väčšine mikroslužieb to avšak potrebné nie je, nakoľko integrácia mikroslužieb je viac prepojená. V takýchto prípadoch máme servisné nástroje, ktoré dokážu vytiahnuť (či už z jednej, alebo z viacerých mikroslužieb + monolitov) všetky relevantné informácie. Služba „DNS Zone History“ nám dokáže poskytnúť zmeny medzi verziami DNS zóny v ľubovoľnom čase, zatiaľ čo „Domain Dirty Digger“ dokáže zo všetkých systémov v priebehu krátkej chvíli vytiahnuť všetku „špinu“ na danú doménu.

11. Deployment

Ak máte obavu z mikroslužieb preto, že potrebujete pre ich chod drahý cloud, vyvedieme vás z omylu. Väčšina mikroslužieb u nás nebeží ani v dockeri. Takmer všetky PHP mikroslužby, ktoré máme, bežia v našom LAMP clusteri (LHC), ktorý poháňa všetky naše webhostingové služby a mikroslužby sa tvária ako obyčajné weby – len komunikujú cez API. RabbitMQ, REDIS a ďalšie podporné služby sú síce mimo clusteru, avšak tie sa dajú nainštalovať nezávisle. Komplikovanejšie a non-PHP mikroslužby bežia na samostatných virtuálnych strojoch. A nakoniec, pre vývoj, testovanie a beh ďalších interných služieb používame jednoduchý “microcloud” postavený nad MAAS+Juju+Kubernetes.

12. R&D, prototypovanie, dokumentácia

Mikroslužby majú aj iné prínosy, ktoré nemusia byť viditeľné na prvý pohľad. Toto uvažovanie zasahuje aj do firemnej kultúry. Manažment firmy sa podstatne menej bojí zmien, nových technológii a je viac naklonený k experimentovaniu. V stabilnom systéme mikroslužieb je riziko zmien a rozšírení podstatne nižšie, ako v systéme založenom na veľkých monolitoch. V konečnom dôsledku tak aj malá firma o 20 ľuďoch môže mať dostatok priestoru na vývoj, testovanie a prototypovanie. Mikroslužba umožňuje vyriešiť problém viacerými spôsobmi. A ak niektorý z tých spôsobov je zlý, skúsite iný.

A ak je veľmi zlý, celý projekt zahodíte a začnete nanovo. Aj keby to už bola vec, ktorá je zavedená v produkcii. Stačí dodržať API.

Dokumentácia? Kód je sám o sebe vždy tou najlepšou dokumentáciou. Nikto nemá v obľube písanie podrobnej dokumentácie a preto to všetko držíme skutočne jednoduché. KISS. Interná wiki obsahuje stránku pre každú mikroslužbu s popisom API a nevyhnutnými informáciami. Vo výsledku, ak mikroslužba pozostáva z piatich súborov a celkovo 200 riadkoch Python kódu (kód frameworkov nerátame), je akákoľvek dokumentácia vcelku zbytočná.

13. Záver

Ďakujeme všetkým, ktorí seriál o mikroslužbách sledujú. Napíšte do komentárov, čo si myslíte o našej adaptácii mikroslužieb, v čom sa vaša adaptácia mikroslužieb odlišovala, alebo či nad mikroslužbami ešte len uvažujete.