Az események diétázása

Bárki írhat olyan kódot, amely néhány hétig vagy hónapig működik, de mi történik, ha ez a kód már nem a napi összpontosít, és az idő pókhálói elkezdnek besurranni? Mi van, ha valaki más kódja? Hogyan adhatunk hozzá új szolgáltatásokat, amikor minden alkalommal újra meg kell tanulni a teljes kódbázist? Hogyan lehet biztos abban, hogy egy apró változtatás az egyik sarokban nem ront el máshol valamit?

A kód összetettsége és összekapcsolása lassú halálspirálba sodorhatja az esetleges őrnagy átírás felé. Megkísérelheti elkerülni ezt a keserű sorsot olyan építészeti minták használatával, mint az eseményvezérelt építészet. Az eseményeken keresztül kommunikáló diszkrét szolgáltatások rendszerének felépítésekor az összekapcsolás csökkentésével korlátozhatja az egyes szolgáltatások összetettségét. Minden szolgáltatás fenntartható anélkül, hogy érintenie kellene az összes többi szolgáltatást az üzleti követelmények minden változásához.

De ha nem vagy óvatos, akkor könnyen rossz szokásokba eshetsz, túl sok adattal töltheted fel az eseményeket, és újból bevezetheted a másfajta összekapcsolást. Vizsgáljuk meg, hogyan történhet ez azáltal, hogy elemezzük az Amazon.com fizetési folyamatát, és megbeszéljük, hogyan lehetne másképp csinálni a dolgokat.

Mit értek esemény alatt?

Mielőtt rátérnénk a fizetési folyamatra, hadd pontosítsam, mit értek az esemény szó alatt. Egy eseménynek két jellemzője van: ez már megtörtént, és releváns a vállalkozás számára. Egy vevő regisztrált, megrendelést adott le, új terméket vett fel - ezek mind példák az üzleti értelmet hordozó eseményekre.

Hasonlítsa ezt össze egy paranccsal. A parancs parancs arra, hogy olyasmit tegyen, ami még nem történt meg, például megrendelést leadni vagy címet megváltoztatni. Gyakran a parancsok és események párban érkeznek. Például, ha a PlaceOrder parancs sikeres, egy OrderPlaced esemény közzétehető, és más szolgáltatások reagálhatnak az eseményre.

A parancsoknak csak egy vevője van: az a kód, amely elvégzi a parancs által kívánt munkát. Például egy PlaceOrder parancsnak csak egy vevője van, mert csak egy darab kód képes a megrendelés leadására. Mivel csak egy vevő van, a parancsot és a kezelési kódot meglehetősen egyszerű megváltoztatni, módosítani és továbbfejleszteni.

Az eseményeket azonban több előfizető fogyasztja. Lehet, hogy két, öt vagy ötven kóddarab reagál a OrderPlaced eseményre, például fizetésfeldolgozás, cikkszállítás, raktárkészlet feltöltése stb. Mivel sok helyre lehet feliratkozni az eseményre, az esemény módosítása nagyot jelenthet hullámzó hatás több különböző rendszeren keresztül, amint hamarosan láthatja.

Vegyünk valamit

Menjünk az Amazon-ba Gregor Hohpe és Bobby Woolf vállalati integrációs mintáinak megvásárlásához, amely értékes olvasmány mindenki számára, aki elosztott rendszereket épít. Meglátogatja az Amazon-ot, beteszi a könyvet a bevásárlókosarába, majd folytatja a fizetést. Mi történik ezután?

Megjegyzés: Az Amazon tényleges fizetési folyamata összetettebb, mint itt bemutatjuk, és folyamatosan változik. Ez az egyszerűsített példa elég jó lesz ahhoz, hogy szemléltesse a lényeget anélkül, hogy túl bonyolult lenne.

Amint végigvezet a fizetési folyamaton, az Amazon összegyűjt egy csomó információt Öntől a megrendelés leadása érdekében. Vizsgáljuk meg röviden, milyen információkra lesz szükség a megrendelés teljesítéséhez:

  • A bevásárlókosárban lévő elemek
  • A szállítási cím
  • Fizetési információk, beleértve a fizetési módot, a számlázási címet stb.

Amikor eléri a fizetési folyamat végét, az összes információ megjelenik az ellenőrzéshez, valamint a „leadja a megrendelést” gomb. A gombra kattintva egy OrderPlaced esemény jelenik meg, amely tartalmazza az összes megadott megrendelési információt, valamint a OrderId-t a megrendelés egyedi azonosításához. Az esemény így nézhet ki:

Az Amazon-szerű rendszeredben lesznek előfizetők erre az eseményre, amelyek a közzététele után működésbe lépnek: számlázzák a megrendelést, módosítják a készletszintet, előkészítik az elemet a szállításhoz és e-mailben elküldik a nyugtát. Lehetnek további előfizetők, akik kezelik a hűségprogramokat, a cikkek árát a népszerűség alapján módosítják, a „gyakran vásárolnak” egyesületeket frissítik, és számtalan egyéb dolgot. A fontos az, hogy néhány nappal később egy új könyv érkezik egy dobozba a küszöbön.

Tehát minden nagyszerű, igaz?

Az esemény dagad

Ez a OrderPlaced esemény leválasztja az internetes réteget a háttérfeldolgozásról, ami jól érzi magát magában, de alattomosabb kapcsolatot rejt, ami később bajba sodorhatja. Ez olyan, mintha túlevés lenne egy nagy családi összejövetelen - pillanatnyilag jó érzés, de végül hasfájás lesz.

Egy ilyen esemény minden szolgáltatást megrabol az autonómiától, mert mindegyikük az értékesítési szolgáltatástól függ a szükséges adatok megadásában. Ezeket a különböző adatokat a LockPlaced eseményszerződés zárja össze. Tehát, ha a Shipping új Amazon Prime szállítási lehetőséget szeretne hozzáadni, akkor ezeket az információkat hozzá kell adni a OrderPlaced eseményhez. A számlázás támogatja a Bitcoint? A OrderPlaced-nak újra módosulnia kell. Mivel az értékesítési szolgáltatás felelős a OrderPlaced eseményért, minden más szolgáltatás az Értékesítéstől függ.

A OrderPlaced esemény minden egyes változásakor elemeznie kell minden előfizetőt, és meg kell vizsgálnia, hogy ezen is változtatnia kell-e. Előfordulhat, hogy a teljes rendszert át kell telepítenie, ez pedig az összes érintett darab tesztelését is jelenti.

Tehát valóban nincs önálló szolgáltatása. Összefüggő szolgáltatások kusza hálója van. Az eseményvezérelt architektúra célja a rendszer szétválasztása volt, hogy az üzleti követelmények megváltoztatása csak az elszigetelt szolgáltatások célzott megváltoztatásával valósuljon meg. De a fent bemutatotthoz hasonló kövér eseményekkel ez lehetetlenné válik.

Gratulálunk, létrehozta Frankenstein szörnyét. Lényegében egy monolit rendszert cseréltél eseményvezérelt elosztott monolit rendszerre. Mi lenne, ha kibontsa ezeket a rendszereket, hogy azok valóban autonómak legyenek?

A diéta ideje

Ha le akarja vágni az eseményt, és harcos formába hozza, diétára kell állítania. Ehhez kezdjük elölről és elemezzük a OrderPlaced esemény minden egyes adatait, és rendeljük hozzá egy adott szolgáltatáshoz.

étrendje

A OrderId és a ShoppingCart a termék értékesítéséhez kapcsolódik, így azok a Sales tulajdonában lehetnek. A ShippingAddress azonban a termékek vevőhöz történő eljuttatására vonatkozik, ezért a szállítási szolgáltatás tulajdonában kell lenniük. A fizetés a termékek fizetésének beszedésére vonatkozik, tehát legyenek számlázási szolgáltatásaink.

Ezekkel a határokkal meghúzva áttekinthetjük a fizetési folyamatot, és megnézhetjük, van-e mód a dolgok javítására.

Karcsúsító

Az eseményeink csökkentésének és a szolgáltatások közötti összekapcsolódásnak az a trükkje, hogy előre hozzuk létre a OrderId-t. Nincs olyan törvény, amely szerint az összes azonosítónak adatbázisból kell származnia. OrderId akkor hozható létre, amikor a felhasználó megkezdi a fizetési folyamatot.

A fizetési folyamatot úgy indíthatja el, hogy egy CreateOrder parancsot küld az értékesítési szolgáltatásnak a OrderId és a kosárban lévő elemek meghatározásához:

A fizetési folyamat következő lépése a szállítási cím kiválasztása volt. Ahelyett, hogy ezeket az adatokat hozzáadná a OrderPlaced eseményhez, mi lenne, ha külön parancsot hozna létre?

A StoreShippingAddressForOrder parancsot elküldheti a webalkalmazásból egyenesen annak a Szállítási szolgáltatásnak, amely az adatokat birtokolja. A megrendelést még ezen a ponton sem adták le, ezért egyelőre nem szállítanak csomagot. Amikor eljön az ideje a megrendelés elküldésének, a Hajózási szolgáltatás már tudja, hova küldje el.

Ha az ügyfél soha nem fejezi be a megrendelést, nem árt elvégeznie ezeket a lépéseket. Valójában értékes üzleti betekintést nyerhetünk az elhagyott bevásárlókocsik elemzéséből, és az a folyamat, amikor kapcsolatba lépünk a bevásárlókocsikat elhagyó felhasználókkal, értékes módszer lehet az eladások növelésére.

Ezután a fizetési folyamatban fizetési információkat kell gyűjtenie az ügyféltől. Mivel a Fizetés a Számlázási szolgáltatás tulajdonosa, ezt a parancsot elküldheti a Számlázásnak:

A Számlázási szolgáltatás még nem terheli a megrendelést - csak rögzítse az információkat, és várja meg, amíg a megrendelést leadják. Ha szervezete nem akarja viselni a hitelkártya-adatok tárolásának biztonsági kockázatát, a fizetést most engedélyezhetjük, és a megrendelés leadását követően lehívhatjuk.

Már csak a megrendelés leadása van hátra. A OrderId előzetes létrehozásával el tudtuk távolítani az adatok többségét, amelyek az eredeti OrderPlaced eseményben voltak, helyette elküldve azokat az egyéb szolgáltatásoknak, amelyek birtokolják ezeket az információkat. Tehát az Értékesítési szolgáltatás most rendkívül egyszerű OrderPlaced eseményt tehet közzé:

Ez a karcsúsított OrderPlaced esemény sokkal koncentráltabb. Az összes felesleges tengelykapcsolót eltávolították. Amint ezt az eseményt a Sales közzétette, a Billing átveszi a már tárolt fizetési információkat, és felszámolja a megrendelést. A hitelkártya sikeres terhelését követően egy OrderBilled eseményt tesz közzé. A szállítási szolgáltatás feliratkozik a OrderPlaced-re a Sales és a OrderBilled from Billing oldalakra, és miután megkapja mindkettőt, tudja, hogy a termékeket a felhasználóhoz szállíthatja.

Vizsgáljuk meg újra a OrderPlaced esemény két verzióját:

Melyik esemény lenne a legkevésbé kockázatos a gyártásban? Melyiket lehetne könnyebben tesztelni? A válasz a kisebb esemény, az összes felesleges tengelykapcsolót eltávolítva.

Harci forma

Az eseményeink karcsúsításának előnye, hogy harci formába hozzák őket, hogy kezeljék az üzleti követelmények változásait, amelyek biztosan megfelelnek a vonalnak. Ha az Amazon Prime szállítást szeretnénk bevezetni, vagy a Bitcoin-ot fizetési módként támogatnánk, most sokkal könnyebb megtenni anélkül, hogy egyáltalán módosítanunk kellene az értékesítési szolgáltatást.

A Prime szállítás támogatása érdekében a CheckShippingTypeForOrder parancsot elküldjük a Szállítási szolgáltatásnak a fizetési szolgáltatás ideje alatt. Valahogy így nézne ki:

Ez lenne a második parancs, amelyet a StoreShippingAddressForOrderrel együtt elküldünk a Shipping szolgáltatásnak. A Prime shipping hozzáadása megváltoztatja a Shipping szolgáltatás előkészítésének módját, de nincs ok a TouchPlaced eseményhez vagy az értékesítési szolgáltatás bármelyik kódjának megérintéséhez.

Hasonló módon néhány különböző módon megvalósíthatnánk a Bitcoint, a Számlázási szolgáltatás gondját. Hozzáadhatnánk a Bitcoin tulajdonságait a StoreBillingDetailsForOrder parancsban használt PaymentDetails osztályhoz. Vagy kidolgozhatnánk egy új parancsot kifejezetten a Bitcoin számára, és ezt elküldhetnénk a StoreBillingDetailsForOrder helyett. Ebben az esetben a Számlázás csak akkor tenné közzé a rendelésszámlát, ha a fizetést a két űrlap egyikével hajtották végre. Végül is a Hajózási szolgáltatás csak azzal törődik, hogy a megrendelést kifizették. Nem érdekli, hogyan.

Mindenesetre a Bitcoin támogatását kizárólag a Számlázási szolgáltatás elemeinek megváltoztatásával valósítanák meg. Az értékesítés és a szállítás teljesen változatlan marad, és nem kellene újból tesztelni vagy átcsoportosítani őket. Ha az egyes változtatások kevesebb felületet érintenek, sokkal gyorsabban alkalmazkodhatunk a változó üzleti követelményekhez.

És ez egyfajta szempont volt az eseményvezérelt architektúra használatához.

Összegzés

Az eseményvezérelt rendszerekben a nagy események a tervezés illata. Próbáljon minél kisebbet tartani az eseményeken. A szolgáltatásoknak valójában csak azonosítókat kell megosztaniuk, és esetleg időbélyegzővel kell megjelölniük, hogy az információ mikor volt hatékony. Ha úgy érzi, hogy ennél több adatot kell megosztani a szolgáltatások között, vegye azt jelzésként arra, hogy esetleg a szolgáltatásai közötti határok tévesek. Gondoljon az architektúrájára az alapján, hogy kinek kell birtokolnia az egyes adatokat, és diétázza ezeket az eseményeket.

A lazán összekapcsolt eseményvezérelt rendszerek létrehozásával kapcsolatos további információkért tekintse meg az NServiceBus lépésről lépésre bemutató útmutatónkat.

A szerzőről: David Boike a Particular Software fejlesztője, aki a pizza és a burritók iránti szerencsétlen affinitása miatt sokkal könnyebben étrendbe hozza eseményeit, mint ő maga.