A microservice architektúráról dióhéjban
Az utóbbi évek egyik legdivatosabb kifejezése az alkalmazásfejlesztés világában a microservice, melyben alkalmazásunk kisebb, egymástól függetlenül telepíthető szolgáltatásokból épül fel. Bár pontos defínicót a microservice kifejezésre még senki sem igazán tudott adni, azért elég jól körülhatárolható, és mivel jelentősége egyre nő, úgy gondoltuk, mi is szentelünk neki egy posztot.
Mi a microservice architektúra?
Alapvetően arról van szó, hogy egy alkalmazást külön processzben futó, egymással valamilyen, viszonylag egyszerű mechanizmussal kommunikáló (ez legtöbbször egy HTTP API) kisebb szolgáltatások összességéből építünk fel.
Ahhoz, hogy jobban megértsük a microserviceket, tekintsük át először, hogyan is működik a klasszikus, monolitikus alkalmazásfejlesztés. Egy monolitikus alkalmazás egyetlen nagy egységet alkot; ha valamely részét megváltoztatjuk, az egész alkalmazást újra kell fordítanunk és telepítenünk/publikálnunk ahhoz, hogy a változások életbe lépjenek.
A monolitikus alkalmazásfejlesztés persze hosszú évek óta sikeres, és bizonyítottan működik is, azonban a közelmúltban számos kritika érte. Az egyik legfőbb, hogy a monolitikus architektúra komplex alkalmazások esetén hátráltatja a gyakori release-eket. Ahogy telik az idő, általában egyre nehezebb tartani a megfelelő modularitást az alkalmazáson belül. A skálázás is nehézségekbe ütközhet, hiszen nehézkes lehet az alkalmazásunk csupán egyetlen komponensének skálázása az igények szerint. Többek között ezek az észrevételek hívták életre a microservice architektúrát.
A microservice architektúra jellemzői
A szoftverfejlesztésben mindig is jelen volt az az igény, hogy az alkalmazásainkat komponensekből építsük fel. Természetesen ezt most is megtesszük, hiszen egy modern szoftver számos library és saját osztály vagy csomag összességéből épül fel.
A microservice-ek ezt a gondolatot viszik eggyel tovább, mert itt a komponensek mind teljesen különálló folyamatok, melyek egymással például web service kérésekkel vagy távoli függvényhívásokkal kommunikálnak.
Ennek a megközelítésnek a legnagyobb előnye, hogy így a különböző komponensek egymástól függetlenül publikálhatóak, frissíthetőek. Ezzel szemben egy klasszikus alkalmazásban ha például frissítjük az egyik általunk használt libraryt, az magával vonja az egész alkalmazás frissítését.
Szerveződés, üzleti folyamatok
Amikor egy nagy alkalmazást részekre bontunk, az azt fejlesztő csapatokat általában a technológiai rétegek alapján képezzük, így jellemzően lesz például egy UI csapat, egy backend fejlesztői gárda, és egy adatbázis csapat. Ennek a szerveződésnek a hátránya, hogy még a legegyszerűbb változtatások is több team koordinációját igényelhetik. Mivel ez sokszor nehézkes, a dolog egyenes következménye, hogy a lefejlesztendő logikát megpróbáljuk egyetlen rétegbe szorítani, hogy elkerüljük ezt az egyeztetési lépést.
Ezzel szemben a microservice architektúrában a felbontás sokkal inkább az üzleti folyamatok mentén történik, így minden service rendelkezik az összes technológiai réteggel, de csak egy adott üzleti igényt elégít ki.
Az új irányzat igyekszik megszünteti a projekt alapú szemléletet is. Klasszikus esetben egy határozott idejű projekt keretében hozunk létre egy alkalmazást, amelyet a projekt végeztével késznek tekintünk, átadjuk egy karbantartási teamnek, és az alkalmazás megbízható működésének fenntartása innentől az ő hatáskörükbe tartozik. Ezzel szemben microservice-ek esetében sokkal inkább az az elv érvényesül, hogy egy adott csapat felelős egy adott service-ért annak teljes élettartama alatt. Ez szorosan összefügg a folyamatos integrációs technikákkal is is, amelyeket a microservice alapú alkalmazások/teamek előszeretettel alkalmaznak.
Okos végpontok, buta csövek
A processzek közötti kommunikációs technológiák közt gyakran találkozunk olyan megoldásokkal, amelyek jelentős logikát építenek magába a kommunikációs közegbe (ennek egyik legjobb példája az Enterprise Service Bus). A microservice architektúrában inkább az "okos végpont, buta cső" elv érvényesül, amely ahogy a neve is mutatja, a lehető legkevesebb logikát építi a kommunikációs rétegbe, és a lehető legtöbbet magukba a service-ekbe. Így nem is meglepő, hogy ezek a komponensek legtöbbször valamilyen REST-szerű protokollon és HTTP-n keresztül kommunikálnak egymással.
A decentralizáltság előnyei és hátrányai
A tény, hogy minden service tulajdonképpen csak egy interfész a másik számára, jelentős rugalmasságot ad a tervezési döntéseket illetően. Azonnal látszik például, hogy nem szükséges az egész alkalmazásunknak ugyanazon a programozási nyelven íródnia, és az sem kell, hogy minden komponens ugyanazzal a domain modellel írja le az üzleti problémát. Az előbbi ritkábban, az utóbbi azonban viszonylag gyakran okoz fejtörést egy nagy enterprise alkalmazás esetén.
Az sem szükséges, hogy a service-ek egyetlen adatbázison dolgozzanak, mindegyikük saját perzisztenciát implementálhat. Ilyenkor azonban természetesen biztosítani kell a konzisztenciát a komponensek között. Ezt legtöbbször tranzakciókkal valósítják meg, de ennek természetesen némi extra komplexitás az ára.
Egy adott komponenst arra is fel kell készítenünk (amivel nem kell számolnunk egy monolitikus szoftver esetén), hogy az általa használt service-ek közül egy vagy több esetleg nem elérhető. Ilyenkor természetesen nem kívánatos, hogy az egész alkalmazásunk összeomoljon, és a klienst is fel kell készítenünk ezekre az eshetőségekre.
Amint látszik, bár elsőre az egész dolog jól hangzik, van azért néhány hátulütő, amire érdemes figyelni. És akkor arról még nem is tettünk említést, hogy a microservice architektúra általában véve képzettebb fejlesztőkel igényel, egy kevésbé képzett csapat esetén rosszul sülhet el, és esetleg egy olyan architektúra születik végül, amely semmilyen előnyt nem nyújt a klasszikus megközelítéssel szemben.
Mivel még kevés a régóta futó, igazán komplex microservice alkalmazás, nehéz megmondani, ez lesz-e a jövő az enterprise alkalmazásfejlesztésben. Mindenesetre a technika legnagyobb pártolói is azt az elvet vallják, hogy nem érdemes egy szoftvert egyből microservice alkalmazásként tervezni; építsünk monolitikus szoftvert, és kezdjük el felbontani, ha ez a monolitikus jelleg már problémássá válik. Egyelőre valószínűleg a legjobb hozzállás a témához az óvatos optimizmus.
Ha részletesebben szeretnél olvasni a microservice architektúráról, érdemes szemügyre venni Martin Fowlerék kiváló ismertetőjét a témában, ill. Sam Newman Building Microservices c. könyvét.