Obsah
1. Některé možné návrhy architektury aplikací založených na mikroslužbách
2. Zamyšlení před přechodem na řešení založené na mikroslužbách…
3. Distribuovaná datová úložiště
4. Příklad databáze v monolitické aplikaci s implementací e-shopu
5. Některé užitečné vlastnosti databáze použité v monolitické aplikaci
6. Databáze v aplikaci postavené na mikroslužbách
7. Dvoufázový commit v mikroslužbách?
8. Další možnost: kompenzační transakce
9. Použití nástrojů pro streaming: záznam a přehrávání sekvence událostí
10. Koncepty, na nichž je streaming založen
11. Nejznámější systémy podporující streaming
13. Nahrávání a přehrávání událostí při použití distribuovaných databází
15. Příklad architektury kappa
16. Přednosti architektury kappa
1. Některé možné návrhy architektury aplikací založených na mikroslužbách
V úvodním článku jsme se seznámili s některými základními koncepty, na nichž jsou postaveny mikroslužby. Připomeňme si, že cílem návrhu architektury aplikace založené na mikroslužbách je dosažení co nejlepší izolace jednotlivých mikroslužeb. Mikroslužby by v naprosté většině případů neměly sdílet databáze a komunikovat by spolu měly pouze přes API volané přes síťové protokoly (nikoli přímo, jak je to možné při běhu na jediném počítači a operačním systému; samozřejmě ani není možné pro komunikaci použít sdílenou paměť). Ovšem ještě lepší bývá stav, kdy spolu služby raději vůbec nekomunikují :-), přesněji řečeno když komunikují pouze přes nějakého prostředníka, kterým může být message bus, message broker, systém pro správu událostí atd.
„It must be possible to feed a team that maintains a service with two pizzas.“
Werner Vogels
Řešení postavené na mikroslužbách přináší některé výhody, například možnost používat různé programovací jazyky a knihovny pro jednotlivé mikroslužby (zmenší se tím pravděpodobnost, že celá obrovská aplikace morálně zastará), provádět paralelní vývoj s několika samostatnými týmy s omezením komunikace mezi těmito týmy, nasazovat jednotlivé služby samostatně, zlepšují se možnosti load balancingu, škálovatelnosti atd. A samozřejmě, protože v IT nedostaneme nic zadarmo, přináší mikroslužby pochopitelně i celou řadu problémů. Dnes se budeme zabývat tím vůbec nejpalčivějším problémem – co s daty, resp. přesněji řečeno jak řešit změnu stavu celé aplikace.
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. Zamyšlení před přechodem na řešení založené na mikroslužbách…
„People try to copy Netflix, but they can only copy what they see. They copy the results, not the process“
Adrian Cockcroft, former Netflix Chief Cloud Architect
Před případným přechodem z monolitických aplikací na mikroslužby je v první řadě dobré si uvědomit jednu důležitou věc. Uživatelské služby typu Netflix a LinkedIn skutečně mikroslužby velmi úspěšně používají (pravděpodobně by ani s jinou architekturou nemohly uspět), ale je tomu tak mj. i z toho důvodu, že typ aplikací/služeb, které provozují, má v podstatě dosti jednoduchou strukturu (stavový prostor), kterou lze relativně snadno rozdělit na mikroslužby. Naproti tomu běžné dennodenně provozované podnikové aplikace sice nemusí dodávat videa nebo publikovat tweeety stovkám milionů uživatelů, ale struktura a provázanost dat v nich bývá mnohem větší. Proto se může velmi dobře stát, že přechod na mikroslužby nemusí být úspěšný, protože na různé aplikace jsou kladeny dosti rozdílné požadavky. Taktéž je nutné upozornit na to, že nasazování a provozování mikroslužeb vyžaduje odlišný přístup, než je tomu u monolitických aplikací. Stručně řečeno: mikroslužby nejsou řešením pro každou situaci a na každý problém!
Přechod na mikroslužby navíc vyžaduje i změnu v myšlení architektů a vývojářů. U monolitické aplikace je vše, zejména změny stavu, v podstatě jednoduché a předvídatelné (ostatně je to důsledek vývoje, který trval přibližně sedm desetiletí) – volání modulů dává zaručené výsledky, databáze typicky podporuje všechny čtyři vlastnosti ACID atd. U mikroslužeb je naproti tomu nutné brát do úvahy zejména problematické vlastnosti počítačové sítě (viz též třináctou kapitolu v předchozím článku) a taktéž důsledky použití několika izolovaných databází.
Velmi pěkně jsou některé vlastnosti (počítačových) sítí shrnuty ve článku Standing on Distributed Shoulders of Giants: Farsighted Physicists of Yore Were Danged Smart!.
3. Distribuovaná datová úložiště
V předchozím článku s úvodními informacemi o mikroslužbách jsme si mj. řekli, že by jednotlivé služby mezi sebou neměly sdílet společnou databázi. Tento požadavek je vlastně pochopitelný, protože se snažíme služby od sebe oddělit, a to jak z hlediska architektury celé aplikace, tak i z pohledu vývojářů – prakticky totiž mohou jednotlivé mikroslužby vyvíjet oddělené týmy, které se musí domluvit na API, ovšem nikoli již na interních záležitostech a logice. A právě sem spadají i databáze, popř. obecněji řečeno datová úložiště – mnoho tabulek a jejich sloupců (pokud se budeme držet relačních databází) nesouvisí s API služby a s její požadovanou vnější funkcionalitou. Na druhou stranu i relativně malá změna v databázovém schématu může rozbít všechny služby, které tuto databázi společně používají.
Přístup k databázím se ve světě mikroslužeb skutečně dosti podstatným způsobem odlišuje od světa monolitických aplikací, a již na začátku je nutné upozornit na to, že mnohé vlastnosti databází, která běžně využíváme (ACID, …) nebudou u mikroslužeb „automagicky“ splněny a mnohdy se programátoři musí sami postarat o to, aby byla příslušná vlastnost databáze skutečně dodržena (pochopitelně jen za předpokladu, že je to skutečně zapotřebí). Na druhou stranu se nám však otevírá celý nový prostor pro nová řešení založená například na perzistentním logu s událostmi atd.
Obrázek 1: Jednotlivé mikroslužby mezi sebou mohou komunikovat například s využitím protokolu HTTP (REST API), STOMP atd. Ovšem důležité je, že každá mikroslužba má svoji databázi.
4. Příklad databáze v monolitické aplikaci s implementací e-shopu
Nejprve si ovšem ve stručnosti ukažme, jakým způsobem může být řešena databáze v monolitické aplikaci při implementaci jednoduchého e-shopu. Soustředit se budeme pouze na její jedinou část – vyřizování objednávek provedených jednotlivými přihlášenými uživateli (u nichž budeme při vyřizování objednávky znát jejich ID).
Obrázek 2: Služba v reálném provozu při použití HTTP serveru, k němuž se připojují klienti.
V tom nejjednodušším případě uvažujme o tom, že databáze bude obsahovat pouhé dvě tabulky nazvané ORDERS a CUSTOMERS. Ve skutečnosti se ovšem pochopitelně bude muset pracovat s více tabulkami, například seznamem zboží pro daný ORDERS.ID, historií nákupů pro CUSTOMERS.ID atd. Tyto tabulky mohou (při značném zjednodušení) vypadat například následovně.
Tabulka CUSTOMERS obsahuje základní informace o zákaznících, přičemž si u každého zákazníka pamatuje i nejvyšší sumu, za kterou tento zákazník může vytvořit objednávku, popř. více objednávek. Business logika aplikace musí zaručit, že tato suma nebude překročena:
CREATE TABLE CUSTOMERS( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, SURNAME VARCHAR (30) NOT NULL, CREDIT_LIMIT DECIMAL(8,2), ... ... ... PRIMARY KEY (ID) );
Tabulka s objednávkami obsahuje seznam všech objednávek, přičemž každá objednávka je na nějakou sumu a navíc je vztažena ke konkrétnímu zákazníkovi. Další sloupce obsahují časové razítko vytvoření objednávky a popř. i její stav:
CREATE TABLE ORDERS( ID INT NOT NULL, DATE DATETIME, CUSTOMER_ID INT NOT NULL references CUSTOMERS(ID), TOTAL DECIMAL(8,2), STATE CHAR(1), ... ... ... PRIMARY KEY (ID) );
Při objednávce zboží je možné nad operacemi v databázi provádět všechny potřebné kontroly, a to většinou naprosto triviálním způsobem. Například můžeme zaručit, že se objednávka podaří jen ve chvíli, kdy bude platit podmínka:
sum(ORDERS.TOTAL) <= CUSTOMER.CREDIT_LIMIT
5. Některé užitečné vlastnosti databáze použité v monolitické aplikaci
To pochopitelně není vše, protože pokud celou operaci objednávky uzavřeme do transakce, zaručí výše zmíněná kontrola automatický rollback celé transakce v případě, že se zákazník bude snažit objednat zboží, jehož celková cena přesahuje jeho maximální povolený limit. Jak kontrolu, tak i transakci lze přitom v monolitické aplikaci s jedinou databází naprogramovat doslova na několika řádcích programového kódu. Dále je možné velmi snadno zaručit automatickou serializaci transakcí pro jednoho zákazníka, tj. vyloučí se například ty situace, kdy se nějaký zákazník bude snažit provést dva nákupy současně, přičemž cena každého nákupu zvlášť se sice vejde do limitní ceny, ale oba nákupy již finanční možnosti zákazníka převyšují. A nakonec – opět díky transakcím – je stav databáze vždy konzistentní, protože se objednávka buď provede (s odečtením kreditu) nebo neprovede, což se například projeví úpravou ORDERS.STATUS na hodnotu „denied“. Nebude zde nutné řešit speciální stavy typu „pending“ atd.
I z hlediska logiky samotné aplikace se jedná o triviální úkol: uživatel stiskne tlačítko Order, aplikace se pokusí provést transakci a pokud transakce proběhla, je o tom uživatel prakticky okamžitě informován, podobně jako bude informován v případě zamítnutí objednávky. Celý kód je proveden synchronně (s případnou výjimkou, která se týká webového UI, ovšem předpokládejme, že zákazník bude moci použít i synchronní API).
6. Databáze v aplikaci postavené na mikroslužbách
V případě, že budeme navrhovat aplikaci s e-shopem postavenou na mikroslužbách, může vést tento návrh k tomu, že se vytvoří (kromě dalších modulů) i mikroslužby nazvané například customer service a order service. Každá z těchto mikroslužeb bude mít i vlastní databázi. Konkrétně v případě první služby bude tato databáze obsahovat tabulku nazvanou ORDERS (plus případné další potřebné tabulky) a druhá služba pak bude obsahovat tabulku CUSTOMERS. Již zde ovšem nebude možné nadeklarovat referenční integritu, tj. definovat cizí klíč v podřízené tabulce ORDERS:
CUSTOMER_ID INT NOT NULL references CUSTOMERS(ID),
Samotné „rozseknutí“ databáze na dvě samostatné databáze však navíc vede k tomu, že ztratíme všechny vlastnosti ACIDu poskytované vlastním databázovým systémem a pokud ACID (či některou z jeho čtyř vlastností) budeme potřebovat, musíme ho nějakým způsobem reimplementovat.
Obrázek 3: Mikroslužby customer service a order service, každá se svou vlastní databází.
7. Dvoufázový commit v mikroslužbách?
V klasických distribuovaných systémech se pro tento účel používá dvoufázový commit neboli two-phase commit, zkráceně též 2PC. Teoreticky je pochopitelně možné dvoufázový commit použít i u aplikace založené na mikroslužbách, ale tento koncept se v praxi příliš nedoporučuje používat, neboť se tím zvyšuje počet zpráv posílaných mezi jednotlivými mikroslužbami, služby jsou na úrovni databází propojené do větší míry, než je většinou akceptovatelné a navíc se tím ztrácí i požadavek na to, aby byla aplikace funkční i při (krátkodobém či střednědobém) výpadku jednotlivých uzlů; zde konkrétně dojde k problému při výpadku uzlu, který celou transakci musí koordinovat. Kromě toho vyžaduje dvoufázový commit předání několika zpráv (minimálně čtyř), což může být u vysoce zatížených aplikací příliš mnoho. A navíc, což je praktičtější problém: mnohé NoSQL databáze, brokery atd. koncept dvoufázového commitu prozatím nepodporují.
8. Další možnost: kompenzační transakce
Jedna z náhrad dvoufázových commitů spočívá ve využití takzvaných kompenzačních transakcí (což s velkou pravděpodobností není ustálený český ekvivalent termínu compensating transaction). Princip je vlastně velmi jednoduchý (o to komplikovanější bývá jeho nasazení v praxi): v každé databázi se provádí změny v transakcích, ovšem pro každou takovou transakci musí existovat i opačná operace, která původní transakci vyruší. Tato kompenzační transakce je typicky vyvolána jinou službou. V našem konkrétním případě by jedna z transakcí spočívala ve vyřízení objednávky pro daného uživatele CUSTOMER.ID ve službě order service. V tento okamžik by byla (například přes orchestraci nebo choreografii) informována služba customer service, aby snížila kredit pro zákazníka. Ovšem pokud kredit klesne na nulu, bude nutné objednávku zrušit – a právě to je úkol pro kompenzační transakci.
Obrázek 4: Transakce a kompenzační transakce. Každá transakce je provedena jinou mikroslužbou, ovšem pokud dojde ke vzniku chyby (malý kredit atd.) je vyvolána zpětná transakce. Na tomto obrázku jsou běžné transakce nazvány Tx, zpětné transakce Cx.
9. Použití nástrojů pro streaming: záznam a přehrávání sekvence událostí
Připomeňme si, že jedním ze základních konceptů, na nichž jsou mikroslužby založeny, je použití vzájemně izolovaných databází pro každou mikroslužbu, což je jeden z přístupů umožňujících škálování jak samotné aplikace, tak i vývojových týmů. Pochopitelně je však nutné nějakým způsobem zajistit, aby se změny provedené v jedné databázi (změna limitu kreditu u zákazníka) nějakým způsobem promítly do další služby. Jedním ze způsobů, jak to zařídit (a to navíc poměrně elegantním způsobem) je využití nástrojů pro streaming. Typicky se jedná o systém Apache Kafka, popř. na Rootu popsaný nástroj NATS Streaming Server. Tyto nástroje umožňují zaznamenávat a později přehrávat (replay) záznamy s informacemi o událostech, k nimž v aplikaci došlo. Na tyto události mohou reagovat další mikroslužby a případně na jejich základu provádět změny ve vlastní databázi.
10. Koncepty, na nichž je streaming založen
Streaming je založen na příjímaní a ukládání zpráv se zaručeným pořadím. Po příjmu je každé zprávě přidělen jednoznačný celočíselný offset (a většinou i časové razítko). To, že každá zpráva uložená do oddílu má přiřazen offset, umožňuje, aby konzumenti zpráv specifikovali, od jakého offsetu potřebují zprávy přijímat. Díky tomu je možné, aby se konzumenti připojovali a odpojovali v jakýkoli okamžik a přitom měli možnost řídit, s jakými zprávami budou pracovat. Konzument se například po pozdějším připojení může rozhodnout, že bude zpracovávat nejnovější data a na případná starší data si (možná) vyhradí svůj strojový čas později. Umožněn je i takzvaný replay, tj. zpracování určité sekvence zpráv z minulosti. Postačuje znát jen offset první zprávy ze sekvence.
Samotné posílání zpráv konzumentů si přitom řídí sami konzumenti, kteří si zprávy (téma+oddíl+offset) musí vyžádat. Díky tomu si sami konzumenti určují, kolik zpráv zpracují a jak tedy budou zatíženi.
To však ve skutečnosti není vše, protože zprávy poslané do message brokera s podporou streamingu se v čase chovají odlišně, než v případě použití běžné fronty. Zprávy jsou totiž rozšířeny o již výše zmíněné pořadové číslo a většinou i o časové razítko. Takto rozšířené zprávy jsou uloženy do takzvaného logu s daným tématem, kde jsou uchovány buď po neomezeně dlouhou dobu, nebo až do chvíle, kdy je překročena kapacita logu, popř. maximální doba životnosti zprávy. Pokud dojde k alespoň jedné této události, budou nejstarší zprávy smazány (kapacita logu je většinou zadána jak celkovým objemem, tak i maximálním počtem zpráv, což je ostatně i případ NATS Streaming Serveru). Nezáleží tedy na tom, zda a kolika konzumenty byla zpráva přečtena a zpracována – přečtení a zpracování zprávy nemá vliv na její umístění v logu, což vlastně znamená, že většinou dochází k určitému zesložitění konzumentů, kteří si musí pamatovat, které zprávy s daným tématem již zpracovaly a které nikoli.
Aby bylo možné konfigurovat a řídit, které zprávy mají být na message brokeru uloženy a které již smazány, specifikuje se takzvaný retention time zajišťující, aby počet zpráv/záznamů nepřekročil časovou mez. Mnohé streaming servery dokážou omezit i celkový počet zpráv, počet zpráv v tématu a/nebo počet zpráv na jednom serveru v clusteru. Totéž omezení je možné aplikovat na celkovou velikost použitého paměťového či diskového prostoru.
Dále se u streaming serverů setkáme s možností zapojení více serverů do clusteru, což podporuje jak dnes popisovaný NATS Streaming Server, tak i Apache Kafka.
11. Nejznámější systémy podporující streaming
Mezi nejznámější a pravděpodobně nejčastěji nasazované systémy podporující streaming patří projekt Apache Kafka a taktéž již dříve popsaný NATS Streaming Server. Použít je možné i službu AWS Kinesis, ovšem Kinesis se většinou používá v jiném kontextu (tímto nástrojem se budeme zabývat v samostatném článku). Nejznámější je ovšem první zmíněný projekt – Apache Kafka.
Obrázek 5: Logo systému Kafka.
Obrázek 6: Logo systému NATS.
Mezi další systémy, tentokrát určené pro záznam neměnitelných logů (událostí), patří například:
- Apache Pulsar
- Azure Cosmos DB Change Feed
- Azure EventHub
- DistributedLog
- Chronicle Queue
- Pravega
12. Apache Kafka
Apache Kafka umožňuje ukládání zpráv (zde se ovšem používá termín záznam – record) do různých témat, přičemž každé téma je rozděleno do oddílů neboli partition (samozřejmě je možné pro téma vyhradit pouze jediný oddíl). Rozdělení do oddílů se provádí z několika důvodů. Jedním z nich je rozdělení zátěže, protože jednotlivé oddíly mohou být provozovány na různých počítačích v clusteru. To však není vše, jelikož je ve skutečnosti konfigurace poněkud složitější – každý oddíl totiž může být replikován na více počítačích, přičemž jeden z těchto oddílů je „leaderem“ a ostatní jsou „followeři“. Zápis nových zpráv, popř. čtení se provádí vždy jen v leaderu, ovšem změny jsou replikovány na všechny kopie oddílu. Ve chvíli, kdy dojde k pádu „leadera“, převezme jeho roli jeden z dalších uzlů. Pokud tedy existuje N uzlů s replikou oddílu, bude systém funkční i ve chvíli, kdy zhavaruje N-1 uzlů!
Téma zpracovávané Kafkou může na clusteru vypadat například následovně:
+---+---+---+---+---+---+ oddíl #0 | 0 | 1 | 2 | 3 | 4 | 5 | ... +---+---+---+---+---+---+ oddíl #1 | 0 | 1 | 2 | ... +---+---+---+ oddíl #2 | ... +---+---+---+---+---+---+---+---+---+ oddíl #3 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ... +---+---+---+---+---+---+---+---+---+
Boxy s čísly odpovídají jednotlivým zprávám, kterým jsou tato pořadová čísla v sekvenci postupně přiřazována. Zápis nových zpráv je prováděn do oblastí označených třemi tečkami. Z tohoto diagramu můžeme odvodit, že každý oddíl obsahuje vlastní sekvenci zpráv/záznamů, ke kterým se postupně připojují záznamy další.
Pozor si musíme dát především na to, že pořadí záznamů je zachováno a garantováno pouze v rámci jednoho oddílu a nikoli pro celé téma. V případě, že požadujeme, aby všechny zprávy v tématu měly zaručené pořadí, používá se pouze jeden oddíl pro celé téma, což má ovšem vliv na další vlastnosti řešení – především se snižuje výkonnost a možnost rozkládání zátěže v rámci clusteru.
Producent při posílání zprávy volí jak téma (což je logické), tak i oddíl. Volbu oddílu je možné provést na základě mnoha kritérií. Například lze použít jednoduchý algoritmus round robin a používat oddíly čistě pro rozložení zátěže. Nebo se může oddíl zvolit například na základě ID přihlášeného uživatele, poslední části IP počítače, na němž je spuštěn producent atd. atd.
Podobně jako u dalších message brokerů s podporou streamování se i v systému Apache Kafka o výběr zpráv, které se mají zpracovat, starají přímo konzumenti, kteří mohou specifikovat offset zprávy. Konzumenti se spojují do skupin, přičemž zprávu získá vždy jeden z konzumentů ze skupiny (což se podobá strategii pub-sub).
Apache Kafka podporuje i speciální API používané ve chvíli, kdy potřebujeme implementovat uzel (proces), který získá zprávu, nějakým způsobem ji zpracuje a poté ji pošle zpět do message brokera. Takový uzel je samozřejmě možné naimplementovat tak, že se bude současně jednat o konzumenta i producenta, ovšem využití speciálního API je efektivnější.
13. Nahrávání a přehrávání událostí při použití distribuovaných databází
Události je do streaming služby možné nahrávat ručně (resp. přesněji řečeno explicitně napsaným programovým kódem), nebo lze využít nástroje typu CDC (Change Data Capture), které dokážou změny stavu prováděné na úrovni databáze (INSERT, UPDATE, DELETE) detekovat a zpracovat automaticky. Mezi tyto nástroje patří zejména Debezium, kterému se budeme věnovat v samostatném článku. Výsledkem explicitně napsaného programového kódu nebo výsledkem práce Debezia je sekvence událostí reflektujících postupně prováděné změny stavu v databázi. Tyto události jsou posílány na streaming server (Kafka, NATS) a odtud si je může (přes mnoho již připravených konektorů) načítat libovolná další služba a adekvátně na ně reagovat (což může vést ke vzniku další události). Předností je tedy fakt, že služby mezi sebou nemají pevnou vazbu a služby, které na události reagují, vůbec nemusí v daný okamžik běžet. K záznamům se totiž lze vracet; jak dlouho do minulosti již záleží na nastavení streaming služby (celkový počet záznamů, časové razítko, obsazení diskového prostoru atd. atd.)
Obrázek 7: Detekce změny v databázích s uložením události do Apache Kafky.
Obrázek 8: Reakce jednotlivých služeb na události. Povšimněte si, že každá služba se může nacházet v jiném stavu zpracování (na jiné události, resp. na jiném offsetu).
14. Architektura kappa
„Databases are global, shared, mutable state. That’s the way it has been since the 1960s, and no amount of NoSQL has changed that. However, most self-respecting developers have got rid of mutable global variables in their code long ago. So why do we tolerate databases as they are?“
Existuje ovšem ještě jedno zajímavé řešení problematiky databází v architekturách založených na mikroslužbách. Toto řešení se někdy nazývá architektura kappa, což je označení používané pro odlišení od známé architektury lambda používané ve streamingu. Toto řešení je založeno na tom, že primárním zdrojem informací o stavu aplikace nejsou samotné SQL či NoSQL databáze, ale přímo události zaznamenané do nástroje pro streaming (typicky se zde používá Apache Kafka). Ovšem i databáze se v této architektuře používají, a to konkrétně ve funkci materializovaných pohledů (materialized views). Každá mikroslužba, která vlastní databázi, postupně přijímá jednotlivé události (změna kreditu u zákazníka, objednávka X kusů zboží Y) a mění obsah své databáze na základě těchto údajů (změna kreditu je UPDATE s přímou změnou hodnoty, objednávka X kusů zboží Y může v mikroslužbě skladu snížit počet dostupných kusů Y o hodnotu X atd. atd.). Takové databáze kvůli nutným zpožděním nebudou obsahovat skutečný stav aplikace, ale „současný stav“, kde je ve skutečnosti ona „současnost“ posunuta oproti reálnému času do minulosti.
15. Příklad architektury kappa
Na devátém obrázku je ukázán příklad jednoduché aplikace používající architekturu kappa. Povšimněte si zejména barevných šipek naznačujících tok dat:
- Červené šipky představují změnu stavu aplikace; informace o této změně je poslána do Apache Kafky či do systému NATS.
- Obsah jednotlivých databází je postupně updatován (modré šipky).
- Databáze přitom slouží jako materializované pohledy pro jednotlivé mikroslužby (zelené šipky).
Obrázek 9: Příklad aplikace používající architekturu kappa.
16. Přednosti architektury kappa
Výše popsaná architektura kappa nabízí až překvapivě velké množství předností, zejména pak:
- Mikroslužby jsou od sebe izolovány, není zapotřebí používat orchestraci atd.
- Pokud se do aplikace přidá nová mikroslužba, naplní se její databáze jednoduše – přehráním všech událostí zaznamenaných v nástroji pro streaming.
- Krátkodobý výpadek nějaké služby nevede ke ztrátě dat, ovšem může vést k viditelnému zpomalení činnosti z pohledu uživatele (potvrzení operace atd. atd.)
- V případě, že je zapotřebí změnit schéma databáze v nějaké mikroslužbě, opět se může její znovunaplnění provést přehráním událostí (čemuž pravděpodobně budeme věřit více, než jednoúčelovému skriptu pro migraci databáze).
- Migrace na zcela jinou databázi (změna dodavatele, přechod SQL→NoSQL či naopak) se opět může provést přehráním událostí.
- A nakonec – celá aplikace získá prakticky zadarmo audit log (audit trail), samozřejmě za předpokladu, že události obsahují všechny důležité informace.
17. Odkazy na Internetu
- Microservices – Not a free lunch!
http://highscalability.com/blog/2014/4/8/microservices-not-a-free-lunch.html - Microservices, Monoliths, and NoOps
http://blog.arungupta.me/microservices-monoliths-noops/ - Microservice Design Patterns
http://blog.arungupta.me/microservice-design-patterns/ - Vision of a microservice revolution
https://www.jolie-lang.org/vision.html - Microservices: a definition of this new architectural term
https://martinfowler.com/articles/microservices.html - Mikroslužby
http://voho.eu/wiki/mikrosluzba/ - Microservice Prerequisites
https://martinfowler.com/bliki/MicroservicePrerequisites.html - Microservices in Practice, Part 1: Reality Check and Service Design (vyžaduje registraci)
https://ieeexplore.ieee.org/document/7819415 - Microservice Trade-Offs
https://www.martinfowler.com/articles/microservice-trade-offs.html - What is a microservice? (from a linguistic point of view)
http://claudioguidi.blogspot.com/2017/03/what-microservice-from-linguisitc.html - Microservices (Wikipedia)
https://en.wikipedia.org/wiki/Microservices - Fallacies of distributed computing (Wikipedia)
https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing - Service (systems architecture)
https://en.wikipedia.org/wiki/Service_(systems_architecture) - Microservices in a Nutshell
https://www.thoughtworks.com/insights/blog/microservices-nutshell - What is Microservices?
https://smartbear.com/solutions/microservices/ - Mastering Chaos – A Netflix Guide to Microservices
https://www.youtube.com/watch?v=CZ3wIuvmHeM&t=17s - Messaging in Microservice Architecture
https://www.youtube.com/watch?v=MkQWQ5f-SEY - Pattern: Messaging
https://microservices.io/patterns/communication-style/messaging.html - Microservices Messaging: Why REST Isn’t Always the Best Choice
https://blog.codeship.com/microservices-messaging-rest-isnt-always-best-choice/ - Protocol buffers
https://developers.google.com/protocol-buffers/ - BSON
http://bsonspec.org/ - Apache Avro!
https://avro.apache.org/ - REST vs Messaging for Microservices – Which One is Best?
https://solace.com/blog/experience-awesomeness-event-driven-microservices/ - How did we end up here?
https://gotocon.com/dl/goto-chicago-2015/slides/MartinThompson_and_ToddMontgomery_HowDidWeEndUpHere.pdf - Scaling microservices with message queues to handle data bursts
https://read.acloud.guru/scaling-microservices-with-message-queue-2d389be5b139 - Microservices: What are smart endpoints and dumb pipes?
https://stackoverflow.com/questions/26616962/microservices-what-are-smart-endpoints-and-dumb-pipes - Common Object Request Broker Architecture
https://en.wikipedia.org/wiki/Common_Object_Request_Broker_Architecture - Enterprise service bus
https://en.wikipedia.org/wiki/Enterprise_service_bus - Microservices vs SOA : What’s the Difference
https://www.edureka.co/blog/microservices-vs-soa/ - Pravda o SOA
https://businessworld.cz/reseni-a-realizace/pravda-o-soa-2980 - Is it a good idea for Microservices to share a common database?
https://www.quora.com/Is-it-a-good-idea-for-Microservices-to-share-a-common-database - Pattern: Shared database
https://microservices.io/patterns/data/shared-database.html - Is a Shared Database in Microservices Actually an Anti-pattern?
https://hackernoon.com/is-shared-database-in-microservices-actually-anti-pattern-8cc2536adfe4 - Shared database in microservices is a problem, yep
https://ayende.com/blog/186914-A/shared-database-in-microservices-is-a-problem-yep - Microservices with shared database? using multiple ORM's?
https://stackoverflow.com/questions/43612866/microservices-with-shared-database-using-multiple-orms - Examples of microservice architecture
https://www.coursera.org/lecture/intro-ibm-microservices/examples-of-microservice-architecture-JXOFj - Microservices: The Rise Of Kafka
https://movio.co/blog/microservices-rise-kafka/ - Building a Microservices Ecosystem with Kafka Streams and KSQL
https://www.confluent.io/blog/building-a-microservices-ecosystem-with-kafka-streams-and-ksql/ - An introduction to Apache Kafka and microservices communication
https://medium.com/@ulymarins/an-introduction-to-apache-kafka-and-microservices-communication-bf0a0966d63 - ACID (computer science)
https://en.wikipedia.org/wiki/ACID_(computer_science) - Distributed transaction
https://en.wikipedia.org/wiki/Distributed_transaction - Two-phase commit protocol
https://en.wikipedia.org/wiki/Two-phase_commit_protocol - Why is 2-phase commit not suitable for a microservices architecture?
https://stackoverflow.com/questions/55249656/why-is-2-phase-commit-not-suitable-for-a-microservices-architecture - 4 reasons why microservices resonate
https://www.oreilly.com/ideas/4-reasons-why-microservices-resonate - Pattern: Microservice Architecture
https://microservices.io/patterns/microservices.html - Pattern: Monolithic Architecture
https://microservices.io/patterns/monolithic.html - Pattern: Saga
https://microservices.io/patterns/data/saga.html - Pattern: Database per service
https://microservices.io/patterns/data/database-per-service.html - Pattern: Access token
https://microservices.io/patterns/security/access-token.html - Databázová integrita
https://cs.wikipedia.org/wiki/Datab%C3%A1zov%C3%A1_integrita - Referenční integrita
https://cs.wikipedia.org/wiki/Referen%C4%8Dn%C3%AD_integrita - Introduction into Microservices
https://specify.io/concepts/microservices - Are Microservices ‘SOA Done Right’?
https://intellyx.com/2015/07/20/are-microservices-soa-done-right/ - The Hardest Part About Microservices: Your Data
https://blog.christianposta.com/microservices/the-hardest-part-about-microservices-data/ - From a monolith to microservices + REST
https://www.slideshare.net/InfoQ/from-a-monolith-to-microservices-rest-the-evolution-of-linkedins-service-architecture - DevOps and the Myth of Efficiency, Part I
https://blog.christianposta.com/devops/devops-and-the-myth-of-efficiency-part-i/ - DevOps and the Myth of Efficiency, Part II
https://blog.christianposta.com/devops/devops-and-the-myth-of-efficiency-part-ii/ - Standing on Distributed Shoulders of Giants: Farsighted Physicists of Yore Were Danged Smart!
https://queue.acm.org/detail.cfm?id=2953944 - Building DistributedLog: High-performance replicated log service
https://blog.twitter.com/engineering/en_us/topics/infrastructure/2015/building-distributedlog-twitter-s-high-performance-replicated-log-servic.html - Turning the database inside-out with Apache Samza
https://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/ - Debezium: Stream changes from your databases.
https://debezium.io/ - Change data capture
https://en.wikipedia.org/wiki/Change_data_capture - Apache Samza (Wikipedia)
https://en.wikipedia.org/wiki/Apache_Samza - Storm (event processor)
https://en.wikipedia.org/wiki/Storm_(event_processor) - kappa-architecture.com
http://milinda.pathirage.org/kappa-architecture.com/ - Questioning the Lambda Architecture
https://www.oreilly.com/ideas/questioning-the-lambda-architecture - Lambda architecture
https://en.wikipedia.org/wiki/Lambda_architecture - Event stream processing
https://en.wikipedia.org/wiki/Event_stream_processing - How to beat the CAP theorem
http://nathanmarz.com/blog/how-to-beat-the-cap-theorem.html - Kappa Architecture Our Experience
https://events.static.linuxfound.org/sites/events/files/slides/ASPgems%20-%20Kappa%20Architecture.pdf