„Napjainkban a mikroszervizek a tökéletes eszközök az agilis szoftverfejlesztési folyamatban.” – Oliver Thylmann
S.O.L.I.D. elvek
Single responsibility principle: Egy objektum egy dologért felel.
Open/closed principle: Az entitások nyitottak a kiterjesztésre, de zártak a módosításra.
Liskov substitution principle: Az objektumok helyettesíthetők altípusokkal.
Interface segregation principle: Többszörös és speciális kliens interfészek.
Dependency inversion principle: A környezet igazodik a magas szintű model interfészhez.
Mikroszerviz jellemzői
- Kevés kódot tartalmaznak (jellemzően 10-100 LOC)
- Nem képezik részét szervizek közötti körkörös hívásoknak.
- 1 vagy 2 pizzás csapat fejleszti. :-)
- Kerüli a szinkron kommunikációt.
- Durva szemcsés műveleteket biztosít (nem bontható kisebb műveletekre)
- A készítő csapat által futtatott.
- Nem vesznek részt összetett szerviz kompozíciókban.
- Szabadságot biztosítanak új keretrendszerek, programozási nyelvek, platformok alkalmazására.
- Saját adatbázisukat kezelik.
- Kifinomult naplózó és monitorozó infrastruktúrával figyelik.
- A Conway tétel által motivált csapatok dolgozzák fel az üzleti igényeket.
- Illeszkednek a DDD (Domain-Driven Design) kontextusra.
- Dinamikusan megismerhetőek.
- Két hét alatt újraírhatóak.
Előnyei
- Telepíthetőség: Gyors elkészülő új verziók, a kisméretű szervizek fejlesztési ciklusa miatt (fejlesztés, tesztelés, élesítés)
- Rendelkezésre állás: Egy szerviz új verziójának élesítése rövid.
- Skálázhatóság: Minden mikroszervíz a saját konténerében egyedileg skálázható (pools, clusters, grids).
- Módosíthatóság: Rugalmasság az új keretrendszerek, könyvtárak, adatforrások és más források implementálásában.
- Menedzsment: Az alkalmazás fejlesztés megosztható csapatok között, így kisebb a munka és sokkal függetlenebbek egymástól.
- Megbízhatóság: A hiba csak egy szervizt érint, így annak javításával elhárítható.
- Tervezési autonómia: A csapat döntése a különböző technológiák, keretrendszerek és tervezési minták használata.
Hátrányai
- Telepíthetőség: A telepítés komplexebb a szervizenkénti telepítési szkriptek, átviteli közegek és a konfigurációs állományok miatt.
- Rendelkezésre állás: Regisztertár használata esetén annak elérhetetlensége minden szervizt megbénít.
- Módosíthatóság: A szervizek közötti kommunikációs utak megváltoztatása sokkal komplexebb.
- Tesztelhetőség: Az automata teszteket sokkal nehezebb implementálni, mivel a különböző mikroszervizek különböző környezetekben futhatnak.
- Menedzsment: Az alkalmazás üzemeltetés erőforrásai növekedhetnek a több napló állomány, komponens és pont-pont interakció miatt.
- Teljesítmény: A hálózati kommunikáció miatt a dinamikus felderítés terhelést okozhat.
- Memória használat: A számos osztály és könyvtár gyakran ismétlődik mikroszervizenként és ez megnöveli a memória használatot.
Mikroszervíz példa
Példa: Kontextus
Tételezzük fel, hogy fejlesztened kell egy szerver-oldali alkalmazást. Az alkalmazásnak támogatnia kell különböző klienseket, az asztali böngészőktől, a mobil böngészőkön keresztül a natív mobil alkalmazásokig. Integrálni kell hozzá további alkalmazásokat, melyek webszervízeken (webservice) vagy üzenetkezelőket (message broker).
Az alkalmazás HTTP kéréseket kezel, hogy:
- megvalósítsa az üzleti logikát,
- elérje az adatbázist,
- kiszolgálja üzenetekkel a többi rendszert,
- és HTML/JSON/XML válaszokkal tér vissza.
Példa: Felvetés
Az alkalmazásnak megfelel a szintekre bontott vagy a hexagonális architektúra, ami tartalmazza az alábbi típusú komponenseket:
- Megjelenítő komponensek – (request, response)
- Üzleti logika – az alkalmazás üzleti logikája
- Adatbázis hozzáférési logika – adatmodellek hozzáféréssel az adatbázishoz
- Alkalmazás integrációs logika – üzenetkezelési szint, mint a RabbitMQ
- További logikai komponensek, melyek az alkalmazás különböző működési területeit kötik össze.
A probléma: Mi lesz az alkalmazás megvalósítási architektúrája?
Megvalósulási architektúra: a logikai architektúra terveitől a fizikai környezetig tartó egység. A fizikai környezet tartalmazza a számítási csomópontokat az intraneten vagy az internet környezetben, a CPU-kat, memóriát, háttértárolókat és minden hardver és hálózati eszközt.
Példa: Megoldás
Tervezzük meg az alkalmazást a Scale Cube segítségével (az y irányú skálázást specifikálva) és funkcionálisan bontsuk szét az alkalmazást egymással együttműködő szolgáltatásokra.
Mindegyik szolgáltatás valósítson meg egy keskeny, de releváns funkcionalitást. Például tételezzük fel, hogy az alkalmazásunk a következő szolgáltatásokból áll: rendelés menedzsment, ügyfél menedzsment, termék menedzsment, stb.
Az összes szolgáltatás egymás közötti kommunikációja szinkron HTTP/REST hívások vagy AMQP (Advanced Messaging Queue Protocol) protokollon keresztüli üzenetek.
A szolgáltatások tervezése és fejlesztése egymástól független.
Minden szolgáltatás saját adatbázissal rendelkezik, jól elhatárolva a többi szolgáltatás adatbázisaitól.
Ha szükséges, az adatbázisok közötti konzisztencia megvalósítására használjunk adatbázis replikációs mechanizmusokat vagy alkalmazásszintű eseményeket.
Példa: A megoldás előnyei
- Minden mikroszervíz viszonylag kicsi.
- A fejlesztőnek könnyebb megérteni
- Az IDE és a web konténer környezet gyorsabb, így nő a produktivitás, a deployment sebesség is
- Minden mikroszervíz külön fejleszthető, frissíthető, különböző verzióval futhat.
- Könnyebben skálázható a fejlesztés. Lehetőség van rá, hogy a fejlesztést több csapat között osszuk el, mindegyiknek egy szervizt adva, így minden csapatnak lehetősége van a saját szervizét fejleszteni, kiegészíteni és skálázni függetlenül a többi csapattól.
- Tökéletes a hiba izoláció. Például, ha memória szivárgás van egy szervízben, akkor az csak azt az egy szervizt kell javítani, a többi szerviz folytathatja a kéréseket kezelését. Összehasonlításként egy monolitikus architektúrában egy nem megfelelően működő komponens az egész rendszerre kihatással van.
- A hosszú távú egész rendszerre kiható technológiai függőségek megszűnnek.
Példa: A megoldás hátrányai
- Az elosztott rendszer miatt a fejlesztőknek jelentős mértékű komplexitás növekedéssel kell számolnia.
- A fejlesztői környezetek monolitikus architektúrákhoz lettek kialakítva és nem igazán támogatják az elosztott alkalmazások fejlesztését.
- A tesztelés bonyolultabbá válik.
- A fejlesztőknek kell kidolgoznia a szervizek közötti belső kommunikációt.
- A több szervizt érintő elosztott tranzakció kezelést megvalósító felhasználói esetek implementálása nehezebb.
- A több szervizt igénylő használati esetek implementálásnál óvatosság és kiváló kommunikáció szükséges a csapatok között.
- Telepítés komplexitása. Élesítéskor a telepítési komplexitás menedzselése és tervezése kiemelt fontosságú a különböző szerviztípusok miatt.
- Megnövekszik a memória fogyasztás. A mikroszervíz architektúra egy N memória szükségletű monolitikus architektúra átalakítása esetén NxM memóriaszükségletű szerviz architektúrát fog képezni. Ha minden mikroszervíz a saját konténerét használja (vagy virtuális gépét), akkor fontos lehet elszeparálni a példányokat vagy a szerver memória M-szer nagyobb lesz. Továbbá, ha minden szervíz a saját konténerében (vagy virtuális gépében fut), mint a Netflix esetén, akkor az még ennél is magasabb lehet.
Hol alkalmazzák?
Netflix, Amazon, Ebay, gov.uk, Twitter, PayPal, SoundCloud
Hasznos anyagok, források
- REST nirvána mikroszervizekkel (Webkonferencia 2014)
- Microservice architecture patterns and best practices
- Eventuate platform
- NGNIX: Introduction to Microservices
- NGNIX: Event-Driven Data Managment for Microservices