Microservice architektúrák
Sziasztok,
mostanában ismerkedek a microservice architektúrákkal,
egy minta projekten dolgozok, amin keresztül ki tudom tapasztalni, hogy
hogyan is kell egy ilyen rendszert felépíteni.
Jelenleg a rendszer, és a különböző szolgáltatások így néznek ki:
- frontend01 (egy PHP-ban írt webalkalmazás, a webes felület megjelenítéséért felel)
- dispatcher01 (RabbitMQ, az üzenetek kézbesítéséért felel a különböző szolgáltatások között)
- entity01 (MySQL, az adatok tárolásáért felel)
- search01 (Solr, az adatokban való keresésért felel)
- graph01 (Neo4j - gráf alapú adatbázis-kezelő, bizonyos adatok gráf formában történő tárolásáért felel pár speciálisabb lekérdezéshez)
- mail01 (Postfix, az emailek kézbesítéséért felel)
Ahogy látszik is, van egy webes frontend, ami a webes felületért, és a megjelenítéséért felel, ezt tudja nyomkodni
a rendszert igénybevevő felhasználó.
Van egy diszpécser, ami egy queue, ez felel a rendszeren belüli üzenetek kézbesítéséért, van egy relációs adatbázis,
ahol az adatokat tároljuk, egy kereső szerver a kereséshez, egy gráf alapú adatbázis-kezelő, itt
az adatok egy bizonyos részét tároljuk, és egy mail szerver az emailek kiküldéséhez.
Tegyük fel, hogy regisztrál egy felhasználó, a felületen, ekkor a következő lépéseknek kell végrehajtódnia:
- létrejön a relációs adatbázis-kezelőben egy sor
- bekerül a kereső szerver indexébe a felhasználó
- bekerül a gráf adatbázis-kezelőbe egy csomópontként a felhasználó
- kiküldésre kerül egy megerősítő email a felhasználónak
- visszajelzünk a felhasználónak a frontend-en, hogy sikeresen regisztrált
Ha egy hagyományos alkalmazásban gondolkodunk, akkor ezeket a lépéseket a PHP script egymás után hajtja végre,
ami egy ilyen művelet esetén sok időt is igénybevehet ugye. A másik megoldás, hogy a frontend szerver
küld egy üzenetet a diszpécsernek, hogy létrejött egy felhasználó, a különböző szolgáltatások pedig figyelik a queue-t,
hogy van-e benne olyan üzenet-típus ami őket érdekelheti, és aszinkron végrehajthatják az általuk elvégzendő műveleteket,
ezzel jelentősen meggyorsítva a dolgot.
A problémáim ezzel a következők:
- mi biztosítja a műveletek sorrendjét? (a megerősítő email addig ne menjen ki, amíg a felhasználó létre nem jött az adatbáziskezelőben)
- tranzakciókezelés (ha a művelet egyik lépése sikertelen volt, akkor mi történik a többivel?)
- hogy tűnik el az adott feladat a queue-ból, ha már mindenki elvégezte a hozzá tartozó feladatot?
- hogyan biztosítsunk azonnali választ a felhasználónak, hogy a regisztráció megtörtént?
Ha valakinek van tapasztalata ilyen rendszerek kialakításában, annak előre is
megköszönöm a segítséget!
■ mostanában ismerkedek a microservice architektúrákkal,
egy minta projekten dolgozok, amin keresztül ki tudom tapasztalni, hogy
hogyan is kell egy ilyen rendszert felépíteni.
Jelenleg a rendszer, és a különböző szolgáltatások így néznek ki:
- frontend01 (egy PHP-ban írt webalkalmazás, a webes felület megjelenítéséért felel)
- dispatcher01 (RabbitMQ, az üzenetek kézbesítéséért felel a különböző szolgáltatások között)
- entity01 (MySQL, az adatok tárolásáért felel)
- search01 (Solr, az adatokban való keresésért felel)
- graph01 (Neo4j - gráf alapú adatbázis-kezelő, bizonyos adatok gráf formában történő tárolásáért felel pár speciálisabb lekérdezéshez)
- mail01 (Postfix, az emailek kézbesítéséért felel)
Ahogy látszik is, van egy webes frontend, ami a webes felületért, és a megjelenítéséért felel, ezt tudja nyomkodni
a rendszert igénybevevő felhasználó.
Van egy diszpécser, ami egy queue, ez felel a rendszeren belüli üzenetek kézbesítéséért, van egy relációs adatbázis,
ahol az adatokat tároljuk, egy kereső szerver a kereséshez, egy gráf alapú adatbázis-kezelő, itt
az adatok egy bizonyos részét tároljuk, és egy mail szerver az emailek kiküldéséhez.
Tegyük fel, hogy regisztrál egy felhasználó, a felületen, ekkor a következő lépéseknek kell végrehajtódnia:
- létrejön a relációs adatbázis-kezelőben egy sor
- bekerül a kereső szerver indexébe a felhasználó
- bekerül a gráf adatbázis-kezelőbe egy csomópontként a felhasználó
- kiküldésre kerül egy megerősítő email a felhasználónak
- visszajelzünk a felhasználónak a frontend-en, hogy sikeresen regisztrált
Ha egy hagyományos alkalmazásban gondolkodunk, akkor ezeket a lépéseket a PHP script egymás után hajtja végre,
ami egy ilyen művelet esetén sok időt is igénybevehet ugye. A másik megoldás, hogy a frontend szerver
küld egy üzenetet a diszpécsernek, hogy létrejött egy felhasználó, a különböző szolgáltatások pedig figyelik a queue-t,
hogy van-e benne olyan üzenet-típus ami őket érdekelheti, és aszinkron végrehajthatják az általuk elvégzendő műveleteket,
ezzel jelentősen meggyorsítva a dolgot.
A problémáim ezzel a következők:
- mi biztosítja a műveletek sorrendjét? (a megerősítő email addig ne menjen ki, amíg a felhasználó létre nem jött az adatbáziskezelőben)
- tranzakciókezelés (ha a művelet egyik lépése sikertelen volt, akkor mi történik a többivel?)
- hogy tűnik el az adott feladat a queue-ból, ha már mindenki elvégezte a hozzá tartozó feladatot?
- hogyan biztosítsunk azonnali választ a felhasználónak, hogy a regisztráció megtörtént?
Ha valakinek van tapasztalata ilyen rendszerek kialakításában, annak előre is
megköszönöm a segítséget!
mi biztosítja a műveletek
Semmi (hacsak te nem kényszeríted ki). frontend -> queue -> mysql -> queue -> postfix legyen az interakció, ne frontend -> queue -> (mysql, postfix)
Legyenek a műveletek idempotensek, azaz akárhányszor megismételhetőek. Ezt írtam rá annó, elég csúnyácska, de a célnak megfelel.
A szinkronizációt neked kell megoldanod, a rabbitmq alapvetően egy üzenetsor, az ilyen komplex logikát neked kell implementálnod. Pl redisben számon tudod tartani melyik job éppen milyen állapotban van.
Hát a mysql válaszát azért érdemes megvárni :). Az amqp alapból ilyet sem tud, erre ezt írtam annó.
Semmi (hacsak te nem
Lényegében akkor az lenne a legelegánsabb, ha egy komplett workflow engine-t hoznék létre, hogy bizonyos üzenettípusok esetén mi az üzenet kezelésének módja/útja. Illetve egy üzenethez tárolni kellene annak az állapotát is.