Eseményvezérelt programozás microservice környezetben 2. rész

A microservice architektúra (MSA) a SOA (szolgáltatás-orientált architektúra) egy továbbgondolt változatának tekinthető, melyben az egyes szolgáltatások kisebbek, csak 1-1 elemi funkciót valósítanak meg. Szakmai cikkünk első részében a rendszerek közötti kommunikáció megvalósítási lehetőségeit ismerteti.

Az alábbi második, befejező rész az eseményvezérelt programozás tervezési mintáiról, és az azok által nyújtott tranzakciókezelési lehetőségekről szól.

Database per Service pattern

A legkönnyebben kivitelezhető tranzakciókezelési megoldás az, ha a szolgáltatások egyetlen, osztott adatbázist használnak és a tranzakciókezelést az adatbáziskezelőre bízzuk. Ezzel azonban nem csak szembe megyünk a microservice architektúra elveivel, miszerint az egyes szolgáltatásoknak egymástól teljesen függetlenül, autonóm módon egy saját kis adatkört kell, hogy kezeljenek, de számos egyéb, a párhuzamos adathozzáférésből fakadó problémát is maga után von. Ezen okok miatt szolgáltatásonként saját adattér (tábla/séma/adatbázis) kialakítása ajánlott.

Ennek a kialakításnak köszönhetően biztosított, hogy egy adatkörhöz ténylegesen csak egy szolgáltatás férhet hozzá, elősegítve ezzel a szolgáltatás autonomitását és a konkurens adathozzáférésből származó problémákat.

Előfordul azonban, hogy az egyik szolgáltatás adatbázisában bekövetkezett változás maga után vonja más szolgáltatásokhoz tartozó adatok változtatását is, melyekről ezeket a szolgáltatásokat értesíteni kell. Ennek hatékony eszköze az event bus-on történő események publikálása, melyre a megfelelő szolgáltatások feliratkoznak és módosítják a saját adatkörükbe a tartozó adatokat.

Eseményvezérelt programozás - Database per service
4. ábra - Database per service (Forrás:http://pluralsight.com)

SAGA pattern

A SAGA pattern lényege, hogy a szolgáltatások az event bus-on keresztül kommunikálnak egymással, felváltva vagy kiegészítve a szinkron HTTP hívásokat. A pattern-nek két alfajtája van:

  • Coreography SAGA
  • Orchestration SAGA

Coreography SAGA

Coreography SAGA pattern kialakítása esetén nincs szükség a teljes kompozíciós logikát egy szolgáltatásban megvalósítani, helyette a tranzakcióban részt vevő szolgáltatások megfelelő események publikálásával jelzik egymásnak a módosítások sikerességét vagy hibáját. Ezáltal egy eseményláncot alkotva alakítják ki a teljes tranzakció lefutását.

Az alábbi ábrán a Coreography SAGA pattern szerint kialakított webshopon keresztüli internetes rendelést reprezántáló működést láthatunk, ahol az ORDER szolgáltatás indítja a tranzakciót, melyben a PAYMENT és SHIPPING szolgáltatás is érintett. Az ORDER szolgáltatás egyiket sem hívja meg közvetlenül, csak egy eseményt publikál, miután a saját adatkörében elvégezte a rendeléshez szükséges módosításokat. Erre az eseményre iratkozik fel a PAYMENT szolgáltatás, az ő eseményére pedig a SHIPPING szolgáltatás. A tranzakcióban utolsó szolgáltatás végül egy olyan eseményt publikál, melyre az ORDER szolgáltatás iratkozik fel, melynek bekövetkeztekor véglegesíti a rendelést.

Eseményvezérelt programozás - Coreography SAGA pattern
5. ábra - Coreography SAGA pattern (Forrás:http://progressivecoder.com/saga-pattern-implementation-with-axon-and-spring-boot-part-1/)

A megvalósítás előnye a gyors átfutási idő és a kompozíciós logika megírásának megspórolása, a későbbiekben pedig a költséghatékony módosítási lehetőség, ugyanis az esemény publikálójának nem kell tudnia, hogy melyik szolgáltatás van feliratkozva az eseményre, így az könnyen cserélhető.

A megoldás hátránya a nehéz nyomon követhetőség. Kompozíciós logika hiányában nehéz megmondani, hogy melyik tranzakció milyen eredménnyel futott le, és hiba esetén a kompenzációs funkciók meghívódtak-e, lefutottak-e.

Orchestration SAGA

Az Orchestration SAGA a kompozit logikát megtartva valósítja meg az eseményvezérelt kommunikációra épülő tranzakciókezelést. A megoldás szerint szükség van a kompozíciós logikát tartalmazó szolgáltatásra, mely sorrendhelyesen hívja meg (eseményvezérelten) a tranzakcióban szükséges szolgáltatásokat.

Az alábbi ábra egy másik webshop internetes rendelési folyamatát reprezentálja, melyben első lépésként az ORDER szolgáltatás előkészíti a rendelést, majd publikálja az ehhez tartozó eseményt. Erre az eseményre a PAYMENT szolgáltatás van feliratkozva, ami a saját művelete elvégzése után szintén publikál egy eseményt, de erre nem a SHIPPING, hanem az ORDER szolgáltatás van feliratkozva. Az ORDER, miután megkapta ezt az eseményt,egy újabb esemény publikálásával „továbblöki” a folyamatot a rá feliratkozó SHIPPING szolgáltatás felé. Amint az ORDER szolgáltatás a SHIPPING-től ismegkapta a pozitív visszajelzést egy eseményt formájában, véglegesíti a rendelést. Az ORDER tehát ebben az architektúrában orchesztrációt végez, minden hívást neki kell kezdeményeznie az adott esemény publikálásával.

Eseményvezérelt programozás - Orchestration SAGA pattern
6. ábra - Orchestration SAGA pattern (Forrás:http://progressivecoder.com/saga-pattern-implementation-with-axon-and-spring-boot-part-1/)

Az Orchestration SAGA előnye a könnyebb nyomon követhetőség a kompozíciós szolgáltatásnak köszönhetően, viszont ezáltal némileg lassul a tranzakció átfutási ideje.

Event sourcing pattern

Az Event sourcing pattern lényege, hogy a rendszer egy entitásnak nem csak az aktuális állapotát, hanem az aktuális állapotig vezető út minden eseményét (létrehozás, módosítás) eltárolja, így minden időpillanatban az események újra játszásával kiolvasható az aktuális állapot. Az entitásokhoz tartozó események egy tartós event store-ban tárolódnak, mely így egy nagy eseményhalmazt alkot, és melybe publikáció során kerülhetnek be új események.

Ezen megoldásnak köszönhetően az entitások írása mindig atomi lesz. Az események az event store-ban sorrendhelyesen, módosíthatatlanul kerülnek tárolásra, az olvasás pedig ezen események újra játszását és az utolsó állapot meghatározását jelenti.

A pattern előnye a konzisztens állapot megtartása, hátránya azonban a nehézkes kivitelezés és üzemeltethetőség, továbbá nem ad egzakt megoldást a konkurens adatmódosításra, nem lehet ugyanis biztosan megállapítani (további fejlesztési megoldások nélkül) egy adat egyidejű módosítása esetén, hogy melyik módosítási esemény került később az event store-ba. Továbbá az olvasási művelet hosszadalmas lehet, mert minden alkalommal az aktuális állapot lekérdezésekor újra kell játszani az entitás teljes „életútját”.

A pattern kiépítése meglehetősen komplex feladat, emiatt bevezetése előtt mindenképpen érdemes mérlegelni, hogy az általa nyújtott érték milyen arányban van a kialakításához és üzemeltetéséhez szükséges erőforrásokkal.

Eseményvezérelt programozás - Event source pattern
7. ábra - Event source pattern (Forrás:https://pluralsight.com)

CQRS pattern

A CQRS pattern az Event sourcing megoldás továbbfejlesztett változata. Ebben az esetben az event store-ban tárolt eseményeket bizonyos időközönként, amikor a teljes rendszer konzisztens állapotban van, egy ütemező újrajátsza az eseményeket és az entitások végső állapotát egy másik adattárba menti. Ennek a megoldásnak köszönhetően az olvasást már testreszabottan lehet optimalizálni, miközben az atomi írás megmarad az event store-nak köszönhetően.

A pattern az event sourcing pattern előnyeit és hátrányainak nagy részét tartalmazza, az időközönkénti áttöltésnek köszönhetően azonban a CQRS patternt használva sokkal gyorsabb olvasás érhető el.

Az Event sourcing-hoz hasonlóan a CQRS pattern kialakítása sem triviális feladat, így itt is érdemes megvizsgálni, vajon megéri-e bevezetni azt egy architektúrában.

Eseményvezrelt programozás - CQRS pattern
8. ábra - CQRS pattern (Forrás: http://pluralsight.com)

Összefoglaló

Egy MSA kialakításánál számtalan aspektusból meg kell vizsgálni a kialakítandó üzleti folyamat megvalósításának mikéntjét, miközben nagyon sok architektúrális döntést kell hozni annak érdekében, hogy a rendszer megfelelően és hatékonyan tudjon működni.

Ilyen kérdéskör az eseményvezérelt kommunikáció és a rá épülő patternek használhatósága is. Több szempontból meg kell vizsgálni annak előnyeit, hátrányait és nem utolsó sorban a patternt megvalósító használandó eszközöket is.

Az eseményvezérelt működés bevezethetőségét és üzemeltetését illetően körültekintően kell eljárni, mert előfordulhat, hogy az üzleti folyamatba az adott pattern nem, vagy csak részben illeszthető be. Például egy elosztott környezetben történő tranzakciókezelésre önállóan egyik pattern sem ad tökéletes megoldást, így elkerülhetetlen azok és az üzleti folyamatok mélyebb ismerete egy ilyen rendszer kialakítása során.

Ettől függetlenül az eseményvezérelt programozás számos esetben megkönnyíti és hatékonyabbá teszi egy rendszer működését, így érdemes megfontolni, hogy hol lehet azt beilleszteni a meglévő vagy az újonnan készülő architektúránkba.

Ajánlott irodalom