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


Kommunikáció mikroszolgáltatás-architektúrában

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 egyetlen folyamaton futó monolitikus alkalmazásokban az összetevők nyelvi szintű metódusok vagy függvényhívások használatával hívják meg egymást. Ezek erősen összekapcsolhatók, ha kóddal (például) hoz létre objektumokat, new ClassName()vagy leválasztott módon hívható meg, ha függőséginjektálást használ, és nem konkrét objektumpéldányokra, hanem absztrakciókra hivatkozik. Akárhogy is, az objektumok ugyanazon a folyamaton belül futnak. A monolitikus alkalmazásról mikroszolgáltatás-alapú alkalmazásra való váltás legnagyobb kihívása a kommunikációs mechanizmus módosítása. A folyamaton belüli metódushívásokból szolgáltatásokra irányuló RPC-hívásokká történő közvetlen átalakítás csevegést és nem hatékony kommunikációt okoz, amely elosztott környezetekben nem fog jól teljesíteni. Az elosztott rendszerek megfelelő tervezésének kihívásai elég jól ismertek ahhoz, hogy még egy olyan vessző is létezik, amelyet az elosztott számítástechnika fallaciesének neveznek, amely felsorolja azokat a feltételezéseket, amelyeket a fejlesztők gyakran tesznek a monolitikusról az elosztott tervekre való áttéréskor.

Nincs egyetlen megoldás, de több. Az egyik megoldás az üzleti mikroszolgáltatások lehető legnagyobb mértékű elkülönítését foglalja magában. Ezután a belső mikroszolgáltatások közötti aszinkron kommunikációt használja, és lecseréli az objektumok közötti folyamaton belüli kommunikációra jellemző finomszemcsés kommunikációt durvaabb szemcsés kommunikációra. Ezt úgy teheti meg, hogy csoportosítja a hívásokat, és több belső hívás eredményét összesítő adatokat ad vissza az ügyfélnek.

A mikroszolgáltatás-alapú alkalmazások olyan elosztott rendszerek, amelyek több folyamaton vagy szolgáltatáson futnak, általában több kiszolgálón vagy gazdagépen is. Minden szolgáltatáspéldány általában folyamat. Ezért a szolgáltatásoknak az egyes szolgáltatások jellegétől függően egy folyamatközi kommunikációs protokollt,például HTTP-t, AMQP-t vagy bináris protokollt, például TCP-t kell használniuk.

A mikroszolgáltatási közösség támogatja az "intelligens végpontok és buta csövek" filozófiáját. Ez a szlogen olyan kialakítást szorgalmaz, amely a mikroszolgáltatások között a lehető legkülönbözőbb, és a lehető legmegtartóbb egyetlen mikroszolgáltatáson belül. Ahogy korábban már elmagyaráztuk, minden mikroszolgáltatás saját adatokkal és saját tartománylogikával rendelkezik. A végpontok közötti alkalmazásokat alkotó mikroszolgáltatások azonban általában egyszerűen rest kommunikációval vannak koreografálva, nem pedig összetett protokollokkal, például WS-* és rugalmas eseményvezérelt kommunikációval központosított üzleti folyamat vezénylők helyett.

A két gyakran használt protokoll a HTTP-kérés/válasz erőforrás API-kkal (a legtöbb lekérdezéskor) és az egyszerűsített aszinkron üzenetküldés, amikor a frissítéseket több mikroszolgáltatáson keresztül kommunikálják. Ezeket részletesebben a következő szakaszokban ismertetjük.

Kommunikációs típusok

Az ügyfél és a szolgáltatások számos különböző típusú kommunikáción keresztül kommunikálhatnak, amelyek mindegyike más-más forgatókönyvet és célokat céloz meg. Kezdetben ezek a kommunikációs típusok két tengelybe sorolhatók.

Az első tengely határozza meg, hogy a protokoll szinkron vagy aszinkron-e:

  • Szinkron protokoll. A HTTP egy szinkron protokoll. Az ügyfél kérést küld, és várja a szolgáltatás válaszát. Ez független attól az ügyfélkód-végrehajtástól, amely lehet szinkron (a szál le van tiltva) vagy aszinkron (a szál nincs letiltva, és a válasz végül visszahívást kap). A lényeg itt az, hogy a protokoll (HTTP/HTTPS) szinkron, és az ügyfélkód csak akkor tudja folytatni a feladatát, amikor megkapja a HTTP-kiszolgáló válaszát.

  • Aszinkron protokoll. Más protokollok, például az AMQP (számos operációs rendszer és felhőkörnyezet által támogatott protokoll) aszinkron üzeneteket használnak. Az ügyfélkód vagy üzenet feladója általában nem várja meg a választ. Csak úgy küldi el az üzenetet, mint amikor üzenetet küld egy RabbitMQ-üzenetsornak vagy bármely más üzenetközvetítőnek.

A második tengely határozza meg, hogy a kommunikáció egyetlen vagy több fogadóval rendelkezik-e:

  • Egy fogadó. Minden kérést pontosan egy fogadónak vagy szolgáltatásnak kell feldolgoznia. Erre a kommunikációra példa a Parancs minta.

  • Több fogadó. Minden kérés nullával több fogadó számára is feldolgozható. Az ilyen típusú kommunikációnak aszinkronnak kell lennie. Ilyen például az olyan mintákban használt közzétételi/előfizetési mechanizmus, mint az eseményvezérelt architektúra. Ez egy event-bus interfészen vagy üzenetközvetítőn alapul, amikor több mikroszolgáltatás közötti adatfrissítéseket propagálja eseményeken keresztül; Általában service buson vagy hasonló összetevőn keresztül implementálják, például az Azure Service Buson keresztül, témakörök és előfizetések használatával.

A mikroszolgáltatás-alapú alkalmazások gyakran használják a kommunikációs stílusok kombinációját. A leggyakoribb típus az egyvevős kommunikáció egy szinkron protokollal, például HTTP/HTTPS használatával egy normál webes API HTTP-szolgáltatás meghívásakor. A mikroszolgáltatások általában üzenetkezelési protokollokat is használnak a mikroszolgáltatások közötti aszinkron kommunikációhoz.

Ezek a tengelyek jó tudni, hogy világos legyen a lehetséges kommunikációs mechanizmusok, de nem ezek a fontos aggodalmak a mikroszolgáltatások létrehozásakor. A mikroszolgáltatások integrálása során sem az ügyfélszál-végrehajtás aszinkron jellege, sem a kiválasztott protokoll aszinkron jellege nem fontos. Fontos , hogy a mikroszolgáltatások aszinkron módon integrálhatók legyenek a mikroszolgáltatások függetlenségének fenntartása mellett, ahogyan az a következő szakaszban is olvasható.

Az aszinkron mikroszolgáltatás-integráció kikényszeríti a mikroszolgáltatás önállóságát

Mint említettük, a mikroszolgáltatásokon alapuló alkalmazások létrehozásakor a mikroszolgáltatások integrálása a fontos szempont. Ideális esetben próbálja meg minimalizálni a belső mikroszolgáltatások közötti kommunikációt. Minél kevesebb kommunikáció van a mikroszolgáltatások között, annál jobb. Sok esetben azonban valahogy integrálnia kell a mikroszolgáltatásokat. Ha ezt kell tennie, a kritikus szabály az, hogy a mikroszolgáltatások közötti kommunikációnak aszinkronnak kell lennie. Ez nem jelenti azt, hogy egy adott protokollt kell használnia (például aszinkron üzenetküldést és szinkron HTTP-t). Ez csak azt jelenti, hogy a mikroszolgáltatások közötti kommunikációt csak az adatok aszinkron propagálásával kell elvégezni, de ne függjön más belső mikroszolgáltatásoktól az eredeti szolgáltatás HTTP-kérési/válaszműveletének részeként.

Ha lehetséges, soha ne függjön több mikroszolgáltatás közötti szinkron kommunikációtól (kéréstől/választól), még a lekérdezések esetében sem. Az egyes mikroszolgáltatások célja, hogy önállóak legyenek, és elérhetők legyenek az ügyfélfelhasználó számára, még akkor is, ha a teljes körű alkalmazás részét képező többi szolgáltatás állapota nem megfelelő vagy nem megfelelő. Ha úgy gondolja, hogy az egyik mikroszolgáltatásból más mikroszolgáltatásokba kell hívást kezdeményeznie (például HTTP-kérést kell végrehajtania egy adat lekérdezéshez), hogy választ tudjon adni egy ügyfélalkalmazásra, olyan architektúrával rendelkezik, amely nem lesz rugalmas, ha egyes mikroszolgáltatások meghibásodnak.

Emellett a mikroszolgáltatások közötti HTTP-függőségek, például a HTTP-kérésláncokkal való hosszú kérés-válasz ciklusok létrehozásakor, ahogyan a 4–15. ábra első részében látható, nem csak a mikroszolgáltatások nem önállóvá teszik a mikroszolgáltatásokat, hanem a teljesítményüket is befolyásolja, amint a lánc egyik szolgáltatása nem teljesít megfelelően.

Minél több szinkron függőséget ad hozzá a mikroszolgáltatások, például a lekérdezési kérelmek között, annál rosszabb lesz az ügyfélalkalmazások általános válaszideje.

Diagram showing three types of communications across microservices.

4–15. ábra. Anti-minták és minták a mikroszolgáltatások közötti kommunikációban

A fenti ábrán látható módon a szinkron kommunikációban a mikroszolgáltatások között kérések "lánca" jön létre az ügyfélkérés kiszolgálása során. Ez egy anti-minta. Az aszinkron kommunikációban a mikroszolgáltatások aszinkron üzeneteket vagy HTTP-lekérdezéseket használnak más mikroszolgáltatásokkal való kommunikációhoz, de az ügyfélkérés azonnal kézbesítve lesz.

Ha a mikroszolgáltatásnak további műveletet kell végrehajtania egy másik mikroszolgáltatásban, ha lehetséges, ne hajtsa végre szinkron módon a műveletet az eredeti mikroszolgáltatás-kérés és válaszművelet részeként. Ehelyett végezze el aszinkron módon (aszinkron üzenetküldési vagy integrációs események, üzenetsorok stb. használatával). De amennyire csak lehetséges, ne hívja meg szinkron módon a műveletet az eredeti szinkron kérés és válasz művelet részeként.

Végül (és itt merül fel a legtöbb probléma a mikroszolgáltatások létrehozásakor), ha a kezdeti mikroszolgáltatásnak olyan adatokra van szüksége, amelyek eredetileg más mikroszolgáltatások tulajdonában vannak, ne támaszkodjon az adatok szinkron kéréseire. Ehelyett replikálja vagy propagálja ezeket az adatokat (csak a szükséges attribútumokat) a kezdeti szolgáltatás adatbázisába végleges konzisztencia használatával (általában integrációs események használatával, a következő szakaszokban leírtak szerint).

Ahogyan azt az egyes mikroszolgáltatás-szakaszok tartománymodell-határainak azonosítása című szakaszban már említettük, egyes adatok több mikroszolgáltatásban való duplikálása nem megfelelő kialakítás – éppen ellenkezőleg, ha az adatokat a további tartomány vagy a kötött környezet adott nyelvére vagy kifejezésére fordíthatja le. Az eShopOnContainers alkalmazásban például egy mikroszolgáltatás van elnevezveidentity-api, amely a felhasználó adatainak többségéért felelős egy elnevezett Userentitással. Ha azonban adatokat kell tárolnia a felhasználóról a Ordering mikroszolgáltatáson belül, azokat egy másik, nevesített Buyerentitásként kell tárolnia. Az Buyer entitás ugyanazzal az identitással rendelkezik az eredeti User entitással, de előfordulhat, hogy csak a tartomány által Ordering igényelt attribútumokkal rendelkezik, és nem a teljes felhasználói profillal.

A végleges konzisztencia érdekében bármilyen protokoll használatával aszinkron módon kommunikálhat és propagálja az adatokat a mikroszolgáltatások között. Mint már említettük, használhat integrációs eseményeket egy eseménybusz vagy üzenetközvetítő használatával, vagy akár HTTP-t is használhat a többi szolgáltatás lekérdezésével. Nem számít. A fontos szabály, hogy ne hozzon létre szinkron függőségeket a mikroszolgáltatások között.

Az alábbi szakaszok a mikroszolgáltatás-alapú alkalmazásokban használható több kommunikációs stílust ismertetik.

Kommunikációs stílusok

A használni kívánt kommunikációs típustól függően számos protokollt és választási lehetőséget használhat a kommunikációhoz. Ha szinkron kérés-/válaszalapú kommunikációs mechanizmust használ, a leggyakoribbak a protokollok, például a HTTP és a REST megközelítések, különösen akkor, ha a szolgáltatásokat a Docker-gazdagépen vagy a mikroszolgáltatási fürtön kívül teszi közzé. Ha belsőleg kommunikál a szolgáltatások között (a Docker-gazdagépen vagy a mikroszolgáltatási fürtön belül), érdemes lehet bináris formátumú kommunikációs mechanizmusokat is használnia (például a TCP-t és a bináris formátumot használó WCF-et). Alternatív megoldásként aszinkron, üzenetalapú kommunikációs mechanizmusokat is használhat, például az AMQP-t.

Több üzenetformátum is létezik, például JSON vagy XML, vagy akár bináris formátum is, ami hatékonyabb lehet. Ha a választott bináris formátum nem szabványos, akkor valószínűleg nem érdemes nyilvánosan közzétenni a szolgáltatásokat ezzel a formátummal. A mikroszolgáltatások közötti belső kommunikációhoz nem szabványos formátumot használhat. Ezt akkor teheti meg, ha a Docker-gazdagépen vagy a mikroszolgáltatás-fürtön (például Docker-vezénylőkön) lévő mikroszolgáltatások közötti kommunikációt, vagy a mikroszolgáltatásokkal kommunikáló, védett ügyfélalkalmazásokat használ.

Kérés-válasz kommunikáció HTTP-vel és REST-tel

Amikor egy ügyfél kérés-válasz kommunikációt használ, kérést küld egy szolgáltatásnak, majd a szolgáltatás feldolgozza a kérést, és visszaküld egy választ. A kérés-válasz kommunikáció különösen alkalmas az ügyfélalkalmazásokból származó valós idejű felhasználói felület (élő felhasználói felület) adatainak lekérdezésére. Ezért egy mikroszolgáltatás-architektúrában valószínűleg ezt a kommunikációs mechanizmust fogja használni a legtöbb lekérdezéshez, amint az a 4–16. ábrán látható.

Diagram showing request/response comms for live queries and updates.

4–16. ábra. HTTP-kérés-/válaszkommunikáció használata (szinkron vagy aszinkron)

Amikor egy ügyfél kérés-válasz kommunikációt használ, feltételezi, hogy a válasz rövid időn belül, általában egy másodpercnél rövidebb vagy legfeljebb néhány másodperc alatt érkezik meg. A késleltetett válaszokhoz az üzenetkezelési mintákon és üzenetkezelési technológiákon alapuló aszinkron kommunikációt kell implementálnia, amely egy másik megközelítés, amelyet a következő szakaszban ismertetünk.

A kérés-válasz kommunikáció népszerű architektúrastílusa a REST. Ez a megközelítés a HTTP protokollon alapul, és szorosan kapcsolódik a HTTP-protokollhoz, amely olyan HTTP-parancsokat használ, mint a GET, a POST és a PUT. A REST a szolgáltatások létrehozásakor leggyakrabban használt architekturális kommunikációs módszer. A REST-szolgáltatásokat ASP.NET Core Web API-szolgáltatások fejlesztésekor implementálhatja.

A HTTP REST-szolgáltatások felületdefiníciós nyelvként való használata esetén további érték áll rendelkezésre. Ha például Swagger-metaadatokkal írja le a szolgáltatás API-t, használhat olyan eszközöket, amelyek ügyfélcsomópontokat hoznak létre, amelyek közvetlenül felderíthetik és felhasználhatják a szolgáltatásokat.

További erőforrások

Leküldéses és valós idejű kommunikáció HTTP-n alapuló

Egy másik lehetőség (általában más célokra, mint a REST) egy valós idejű és egy-a-többhöz kommunikáció magasabb szintű keretrendszerek, mint például ASP.NET SignalR és protokollok, mint a WebSockets.

Ahogy a 4–17. ábrán látható, a valós idejű HTTP-kommunikáció azt jelenti, hogy a kiszolgálókód a tartalom csatlakoztatott ügyfelekre való leküldését jelenti, miközben az adatok elérhetővé válnak, ahelyett, hogy a kiszolgáló megvárná, amíg az ügyfél új adatokat kér.

Diagram showing push and real-time comms based on SignalR.

4–17. ábra. Egy-a-többhöz valós idejű aszinkron üzenetkommunikáció

A SignalR jó módja annak, hogy valós idejű kommunikációt érjen el, ha tartalmat küld az ügyfeleknek egy háttérkiszolgálóról. Mivel a kommunikáció valós időben történik, az ügyfélalkalmazások szinte azonnal megjelenítik a változásokat. Ezt általában egy olyan protokoll kezeli, mint a WebSockets, amely számos WebSockets-kapcsolatot használ (ügyfélenként egyet). Tipikus példa erre az, amikor egy szolgáltatás egyszerre több ügyfél-webalkalmazásnak is közli a sportjátékok pontszámának változását.