Megosztás a következőn keresztül:


Aszinkron üzenetalapú kommunikáció

Tipp.

Ez a tartalom egy részlet a .NET-alkalmazásokhoz készült .NET-alkalmazásokhoz készült eBook, .NET Microservices Architecture című eBookból, amely elérhető a .NET Docs-on vagy egy ingyenesen letölthető PDF-fájlként, amely offline módban is olvasható.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Az aszinkron üzenetkezelés és az eseményvezérelt kommunikáció kritikus fontosságú a módosítások több mikroszolgáltatásban és azok kapcsolódó tartománymodelljeiben való propagálása során. Amint azt a vita során már említettük, a mikroszolgáltatások és a kötött környezetek (BCs) modelljei (Felhasználó, Ügyfél, Termék, Fiók stb.) különböző dolgokat jelenthetnek a különböző mikroszolgáltatásokban vagy BCs-kben. Ez azt jelenti, hogy ha változások történnek, valamilyen módon össze kell hangolnia a változásokat a különböző modellek között. A megoldás az aszinkron üzenetkezelésen alapuló végleges konzisztencia és eseményvezérelt kommunikáció.

Üzenetküldés használatakor a folyamatok az üzenetek aszinkron cseréjével kommunikálnak. Az ügyfél egy üzenet küldésével parancsot vagy kérést küld egy szolgáltatásnak. Ha a szolgáltatásnak válaszolnia kell, egy másik üzenetet küld vissza az ügyfélnek. Mivel üzenetalapú kommunikációról van szó, az ügyfél feltételezi, hogy a válasz nem érkezik meg azonnal, és lehet, hogy egyáltalán nem lesz válasz.

Az üzeneteket fejléc (metaadatok, például azonosítási vagy biztonsági információk) és egy törzs alkotja. Az üzeneteket általában aszinkron protokollok, például az AMQP küldik.

A mikroszolgáltatások közösségében az ilyen típusú kommunikáció elsődleges infrastruktúrája egy egyszerű üzenetközvetítő, amely különbözik az SOA-ban használt nagy közvetítők és vezénylőkétől. Egy egyszerűsített üzenetközvetítőben az infrastruktúra általában "buta", csak üzenetközvetítőként működik, olyan egyszerű implementációkkal, mint a RabbitMQ vagy egy méretezhető service bus a felhőben, például az Azure Service Bus. Ebben a forgatókönyvben az "intelligens" gondolkodás nagy része továbbra is az üzeneteket létrehozó és fogyasztó végpontokban, vagyis a mikroszolgáltatásokban él.

Egy másik szabály, amelyet a lehető legnagyobb mértékben követnie kell, az, hogy csak aszinkron üzenetküldést használjon a belső szolgáltatások között, és csak az ügyfélalkalmazásoktól az előtérbeli szolgáltatásokig (API Gateways és a mikroszolgáltatások első szintje) használjon szinkron kommunikációt (például HTTP).

Kétféle aszinkron üzenetkommunikáció létezik: egy fogadó üzenetalapú kommunikáció és több fogadó üzenetalapú kommunikációja. A következő szakaszok részletesen ismertetik őket.

Egy fogadó üzenetalapú kommunikáció

Az üzenetalapú aszinkron kommunikáció egyetlen fogadóval azt jelenti, hogy pont–pont kommunikációval pontosan az egyik felhasználónak küld üzenetet, aki a csatornáról olvas, és az üzenet feldolgozása csak egyszer történik. Vannak azonban különleges helyzetek. Például egy felhőrendszerben, amely megpróbál automatikusan helyreállni a hibákból, ugyanazt az üzenetet többször is újra lehet küldeni. Hálózati vagy egyéb hibák miatt az ügyfélnek újra meg kell tudnia küldeni az üzeneteket, és a kiszolgálónak egy idempotens műveletet kell implementálnia ahhoz, hogy egy adott üzenetet csak egyszer dolgozhasson fel.

Az egy fogadó üzenetalapú kommunikáció különösen alkalmas arra, hogy aszinkron parancsokat küldjön az egyik mikroszolgáltatásból a másikba a 4–18. ábrán látható módon, amely ezt a megközelítést szemlélteti.

Miután megkezdte az üzenetalapú kommunikáció küldését (parancsokkal vagy eseményekkel), kerülnie kell az üzenetalapú kommunikáció és a szinkron HTTP-kommunikáció keveredését.

A single microservice receiving an asynchronous message

4–18. ábra. Egyetlen mikroszolgáltatás, amely aszinkron üzenetet fogad

Amikor a parancsok ügyfélalkalmazásokból származnak, http-szinkron parancsokként implementálhatók. Akkor használjon üzenetalapú parancsokat, ha nagyobb méretezhetőségre van szüksége, vagy ha már egy üzenetalapú üzleti folyamatban van.

Több fogadó üzenetalapú kommunikációja

Rugalmasabb megközelítésként érdemes lehet egy közzétételi/előfizetési mechanizmust is használni, hogy a küldőtől érkező kommunikáció további előfizetői mikroszolgáltatások vagy külső alkalmazások számára is elérhető legyen. Így segít követni a küldési szolgáltatás nyitott/zárt elvét . Így a jövőben további előfizetők is hozzáadhatók anélkül, hogy módosítani kellene a küldő szolgáltatást.

Amikor közzétételi/előfizetési kommunikációt használ, előfordulhat, hogy eseménybusz-felületet használ az események bármely előfizető számára való közzétételéhez.

Aszinkron eseményvezérelt kommunikáció

Az aszinkron eseményvezérelt kommunikáció használatakor a mikroszolgáltatások egy integrációs eseményt tesznek közzé, amikor valami történik a tartományán belül, és egy másik mikroszolgáltatásnak tisztában kell lennie vele, például egy termékkatalógus mikroszolgáltatásának árváltozásával. További mikroszolgáltatások feliratkoznak az eseményekre, hogy aszinkron módon fogadhassák őket. Ilyen esetben a fogadók frissíthetik a saját tartományi entitásaikat, ami további integrációs események közzétételét okozhatja. Ez a közzétételi/előfizetési rendszer egy eseménybusz implementálásával történik. Az eseménybusz absztrakcióként vagy interfészként is tervezhető, az eseményekre való feliratkozáshoz vagy leiratkozáshoz és események közzétételéhez szükséges API-val. Az eseménybusz egy vagy több olyan implementációval is rendelkezhet, amely bármilyen folyamatközi és üzenetközvetítőn alapul, például egy üzenetsoron vagy service buson, amely támogatja az aszinkron kommunikációt és a közzétételi/feliratkozási modellt.

Ha egy rendszer integrációs eseményeken alapuló végleges konzisztenciát használ, javasoljuk, hogy ezt a megközelítést egyértelművé tegyük a végfelhasználó számára. A rendszernek nem szabad olyan megközelítést használnia, amely az integrációs eseményeket utánozza, például a SignalR-t vagy az ügyféltől származó lekérdezési rendszereket. A végfelhasználónak és az üzleti tulajdonosnak explicit módon fel kell használnia a rendszer végleges konzisztenciáját, és tisztában kell lennie azzal, hogy sok esetben az üzletnek nincs problémája ezzel a megközelítéssel, amíg explicit. Ez a megközelítés azért fontos, mert a felhasználók elvárhatják, hogy azonnal láthassanak néhány eredményt, és ez a szempont nem feltétlenül fordul elő végleges konzisztenciával.

Ahogy azt az elosztott adatkezeléssel kapcsolatos kihívások és megoldások című szakaszban már említettük, az integrációs események segítségével több mikroszolgáltatásra kiterjedő üzleti feladatokat valósíthat meg. Így végső konzisztenciája lesz a szolgáltatások között. Egy végül konzisztens tranzakció elosztott műveletek gyűjteményéből áll. Minden műveletnél a kapcsolódó mikroszolgáltatás frissíti a tartományi entitást, és közzétesz egy másik integrációs eseményt, amely a következő műveletet ugyanazon a végpontok közötti üzleti feladaton belül hajtja végre.

Fontos szempont, hogy több olyan mikroszolgáltatásnak is kommunikálnia kell, amelyek ugyanarra az eseményre vannak előfizetve. Ehhez használhatja a közzétételi/előfizetési üzenetküldést az eseményvezérelt kommunikáció alapján, ahogyan az a 4–19. ábrán látható. Ez a közzétételi/előfizetési mechanizmus nem kizárólagos a mikroszolgáltatás-architektúrára. Hasonló ahhoz, ahogyan a DDD-ben a kötött környezeteknek kommunikálniuk kell, vagy ahogyan a frissítéseket az írási adatbázisból az olvasási adatbázisba propagálja a Parancs- és lekérdezési felelősségi elkülönítés (CQRS) architektúra mintájában. A cél az, hogy az elosztott rendszer több adatforrása között végleges konzisztenciát biztosítsunk.

Diagram showing asynchronous event-driven communications.

4–19. ábra. Aszinkron eseményvezérelt üzenetkommunikáció

Az aszinkron eseményvezérelt kommunikációban egy mikroszolgáltatás eseményeket tesz közzé egy eseménybuszon, és számos mikroszolgáltatás előfizethet rá, hogy értesítést kapjon és cselekedjen rajta. A megvalósítás határozza meg, hogy milyen protokollt használjon az eseményvezérelt, üzenetalapú kommunikációhoz. Az AMQP segíthet a megbízható üzenetsoros kommunikáció elérésében.

Eseménybusz használatakor érdemes lehet absztrakciós szintet (például eseménybusz-felületet) használni az osztályok kapcsolódó implementációján alapuló absztrakciós szinttel, amely egy üzenetközvetítő API-ját használó kóddal rendelkezik, például a RabbitMQ vagy egy service bus, például az Azure Service Bus témakörökkel. Másik lehetőségként érdemes lehet egy magasabb szintű szolgáltatásbuszt, például az NServiceBust, a MassTransitet vagy a Brightert használni az eseménybusz tagolási és közzétételi/előfizetési rendszeréhez.

Megjegyzés az éles rendszerek üzenetkezelési technológiáiról

Az absztrakt eseménybusz implementálható üzenetkezelési technológiái különböző szinteken érhetők el. Például az olyan termékek, mint a RabbitMQ (üzenettovábbító átvitele) és az Azure Service Bus alacsonyabb szinten ülnek, mint más termékek, például az NServiceBus, a MassTransit vagy a Brighter, amelyek a RabbitMQ és az Azure Service Bus tetején működnek. A választás attól függ, hogy az alkalmazás szintjén hány gazdag funkcióra és a beépített méretezhetőségre van szüksége az alkalmazáshoz. Ahhoz, hogy csak egy megvalósíthatósági igazolást tartalmazó eseménybuszt implementáljon a fejlesztési környezethez, mivel az eShopOnContainers mintában történt, elegendő lehet egy Docker-tárolón futó RabbitMQ egyszerű implementációja.

A hiperskálázhatóságot igénylő kritikus fontosságú és éles rendszerek esetében azonban érdemes lehet kiértékelni az Azure Service Bust. Az elosztott alkalmazások fejlesztését megkönnyítő, magas szintű absztrakciók és funkciók érdekében javasoljuk, hogy értékelje ki az egyéb kereskedelmi és nyílt forráskódú szolgáltatásbuszokat, például az NServiceBust, a MassTransitet és a Brightert. Természetesen létrehozhatja saját service-bus funkcióit az alacsonyabb szintű technológiákra, például a RabbitMQ-ra és a Dockerre. Ez a vízvezeték-munka azonban túl sokba kerülhet egy egyéni nagyvállalati alkalmazás esetében.

Rugalmas közzététel az eseménybuszon

Egy eseményvezérelt architektúra több mikroszolgáltatásban való implementálása során kihívást jelent az eredeti mikroszolgáltatás állapotának atomi frissítése, miközben a kapcsolódó integrációs eseményt rugalmasan közzéteszi az eseménybuszban, valahogy tranzakciók alapján. Az alábbiakban bemutatunk néhány módszert ennek a funkciónak a megvalósítására, bár lehetnek további megközelítések is.

  • Tranzakciós (DTC-alapú) üzenetsor használata, például MSMQ. (Ez azonban egy örökölt megközelítés.)

  • Tranzakciónapló-bányászat használata.

  • Teljes event sourcing minta használata.

  • A Kimenő üzenetek minta használata: egy tranzakciós adatbázistábla üzenetsorként, amely egy esemény-létrehozó összetevő alapja lesz, amely létrehozza és közzéteszi az eseményt.

Az ezen a téren jelentkező kihívások teljesebb leírásáért, beleértve a potenciálisan helytelen adatokkal rendelkező üzenetek közzétételének módját, tekintse meg az Azure-beli kritikus fontosságú számítási feladatok adatplatformját: Minden üzenetet fel kell dolgozni.

Az aszinkron kommunikáció használatakor további megfontolandó témakörök az üzenet idempotenssége és az üzenetdeduplikáció. Ezeket a témaköröket az útmutató későbbi, a mikroszolgáltatások (integrációs események) közötti eseményalapú kommunikáció megvalósítása című szakasza ismerteti.

További erőforrások