neděle 16. března 2014

Svět mikro služeb

Architektura většiny aplikací odpovídá jedné velké kouli bahna, pro kterou se vžilo označení monolitická. Na úrovni aplikace jsou typickými rysy bobtnající závislosti na knihovnách, vzájemné svázané části aplikace vedoucí k nulové odolnosti vůči selhání jednotlivých částí. Na úrovni operačního systému se jedná o jeden velký proces s velkými nároky na zdroje. Monolitické aplikace mají jednu obrovskou výhodu a to je jednoduchost vývoje. Nemusíte řešit, jak bude daný kód spolupracovat se zbytkem systému, prostě ho napíšete a on se stane součástí aplikace. Monolitické aplikace mají ovšem celou řadu nevýhod. Můžete je škálovat pouze jako celek. To vede k neoptimálnímu využití zdrojů. V případě selhání jedné části aplikace, byť absolutně nekrytické pro fungování z pohledu uživatele, dochází lavinovitě k selhání celé aplikace. Klasickým příkladem může být memory leak, který postihne celou aplikaci. Alternativou k monolitickému uspořádání aplikace představuje architektura micro services.


Architektura micro services vychází z toho, že aplikace a její funkcionalita se skládá z velkého množství malých služeb pospojovaných do větších celků. Důležitou charakteristikou tohoto architektonického přístupu je nebo by měla být izolovanost jednotlivých služeb. Adrian Cockcroft (Netflix, eBay, Sun) prosazoval myšlenku, že každá mikro služba může selhat a její konzumenti s tím musí apriori počítat. Byl to právě Adrian Cockcroft a firma Netflix pod jeho vedením, která postavila celý svůj stack právě na této architektuře.


Na velikosti záleží

Velikost mikro služby se těžko kvantifikuje. Četl jsem názory, že by to mělo být maximálně pár stovek řádků kódu, ale to mi nepřijde směrodatné. Mnohem důležitějším aspektem je dodržení takzvané jedné odpovědnosti (single responsibility principle). Každá mikro služba by měla dělat právě a jenom jednu věc - login, checkout, hledání, zobrazení nákupního košíku atd. V případě REST rozhraní mi přijde jako vhodná granularita jeden resource odpovídající mikro službě nebo alespoň funkcionalita z pohledu uživatele. Docela velkým nebezpečím je opačný extrém, tedy že aplikaci příliš fragmentujete vytvořením stovek mikro služeb. Každá mikro služba má svoje nároky, například v Jave musíte počítat s režií pro JVM, a musíte počítat se síťovým overheadem pro každou komunikaci mezi jednotlivými mikro službami. Někde jsem viděl poměrně vtipné přirovnání, že mikro služby představují Enterprise Java Beans pro hipstery.


Skryté náklady

Nejvíce přitažlivé na monolitické architektuře jsou nulové náklady, které máte s přidáváním nových vlastností do aplikace. V případě mikro služeb potřebujete poměrně slušnou infrastrukturu a to pro každou ze služeb. Řekněme, že máme mikro služby, které mají všechny jednotné REST rozhraní (HTTP, JSON). Pro každou z mikro služeb potřebujete kontejner, ve kterém poběží. Potřebujete monitoring, alerting. Každá z mikro služeb by měla být high available. Klienti služeb, další mikro služby, se musí nějakým způsobem dozvědět kde tyto služby běží. Můžete začít tím, že endpointy služeb bude někde v konfiguraci, ale dříve nebo později budete potřebovat nějaký registr služeb a jejich endpointů, protože služby mohou vznikat v nových verzích a nebo kolabovat v průběhu života celé aplikace. To se bavíme jenom o nárocích na běhové prostředí, k tomu je potřeba připočítat automatizaci na úrovni deploymentu (Puppet, Chef).


Kdy začít

Vždycky když merguji pull request, trnu hrůzou z představy, aby nějaká chyba nesprovodila ze světa celý server a já nemusel vstávat ve dvě hodiny ráno a něco řešit. Můžete si zkusit aplikaci rozdělit na kritické a nekritické komponenty z pohledu uživatele, zkusit se zamyslet, jestli byste mohli efektivně škálovat jednotlivé části aplikace, ale nejspolehlivější indikátor je obava, že už vám komplexita aplikace přerůstá přes hlavu. V takovou chvíli je vhodné začít přemýšlet o mikro službách. Velkou výhodou tohoto architektonického přístupu je, že můžete migrovat postupně jednotlivé části aplikace. Nemusí se hned od začátku jednat o velký třesk. Mikro služby nejsou sami o sobě spásou, i zde můžete udělat chybu, ale pokud to uděláte dobře, je velká pravděpodobnost, že chyba složí jenom jednu malou část aplikace.

Zdroje a užitečné odkazy