Implementace komunikace mezi mikroslužbami založené na událostech (události integrace)
Tip
Tento obsah je výňatek z eBooku, architektury mikroslužeb .NET pro kontejnerizované aplikace .NET, které jsou k dispozici na .NET Docs nebo jako zdarma ke stažení PDF, které lze číst offline.
Jak bylo popsáno dříve, když používáte komunikaci založenou na událostech, mikroslužba publikuje událost, když se stane něco, co se stane, například když aktualizuje obchodní entitu. Ostatní mikroslužby se k odběru těchto událostí přihlašují. Když mikroslužba přijme událost, může aktualizovat své vlastní obchodní entity, což může vést k publikování dalších událostí. Toto je podstata konceptu konečné konzistence. Tento systém publikování/odběru se obvykle provádí pomocí implementace sběrnice událostí. Sběrnici událostí je možné navrhnout jako rozhraní s rozhraním API, které je potřeba k přihlášení k odběru a odhlášení odběru událostí a k publikování událostí. Může mít také jednu nebo více implementací na základě jakékoli komunikace mezi procesy nebo zasílání zpráv, jako je fronta zasílání zpráv nebo sběrnice služby, která podporuje asynchronní komunikaci a model publikování/odběru.
Události můžete použít k implementaci obchodních transakcí, které zahrnují více služeb, které poskytují konečnou konzistenci mezi těmito službami. Nakonec konzistentní transakce se skládá z řady distribuovaných akcí. V každé akci mikroslužba aktualizuje obchodní entitu a publikuje událost, která aktivuje další akci. Mějte na paměti, že transakce nepřesahuje základní trvalost a sběrnice událostí, takže idempoteence je potřeba zpracovat. Obrázek 6–18 níže ukazuje událost PriceUpdated publikovanou prostřednictvím sběrnice událostí, takže aktualizace cen se rozšíří do košíku a dalších mikroslužeb.
Obrázek 6–18 Komunikace založená na událostech založená na sběrnici událostí
Tato část popisuje, jak můžete implementovat tento typ komunikace s .NET pomocí obecného rozhraní sběrnice událostí, jak je znázorněno na obrázku 6–18. Existuje několik potenciálních implementací, z nichž každá používá jinou technologii nebo infrastrukturu, jako je RabbitMQ, Azure Service Bus nebo jakýkoli jiný open source nebo komerční sběrnice třetích stran.
Použití zprostředkovatelů zpráv a servisních autobusů pro produkční systémy
Jak je uvedeno v části architektura, můžete si vybrat z několika technologií zasílání zpráv pro implementaci abstraktní sběrnice událostí. Tyto technologie jsou ale na různých úrovních. Například RabbitMQ, přenos zprostředkovatele zasílání zpráv, je na nižší úrovni než komerční produkty, jako je Azure Service Bus, NServiceBus, MassTransit nebo Brighter. Většina z těchto produktů může fungovat nad RabbitMQ nebo Azure Service Bus. Volba produktu závisí na tom, kolik funkcí a kolik předefinovaných škálovatelností pro vaši aplikaci potřebujete.
Pro implementaci pouze testování konceptu sběrnice událostí pro vaše vývojové prostředí, stejně jako v ukázce eShopOnContainers, může být dostatečná jednoduchá implementace nad RabbitMQ běžící jako kontejner. V případě důležitých a produkčních systémů, které potřebují vysokou škálovatelnost, ale možná budete chtít vyhodnotit a používat Službu Azure Service Bus.
Pokud požadujete abstrakce vysoké úrovně a bohatší funkce, jako jsou Sagas pro dlouhotrvající procesy, které usnadňují distribuovaný vývoj, další komerční a opensourcové servisní autobusy, jako jsou NServiceBus, MassTransit a Brighter , stojí za to vyhodnotit. V tomto případě by abstrakce a rozhraní API, které se mají použít, obvykle byly přímo ty, které poskytují tyto sběrnice vysoké úrovně místo vlastních abstrakcí (například jednoduché abstrakce sběrnice událostí poskytované na eShopOnContainers). V takovém případě můžete prozkoumat forked eShopOnContainers pomocí NServiceBus (další odvozená ukázka implementovaná konkrétním softwarem).
Samozřejmě byste vždy mohli vytvářet vlastní funkce service bus nad technologiemi nižší úrovně, jako je RabbitMQ a Docker, ale práce potřebná k "opětovnému vytvoření kola" může být pro vlastní podnikovou aplikaci příliš nákladná.
Opakovat: ukázkové abstrakce sběrnice událostí a implementace, které jsou prezentovány v ukázce eShopOnContainers, jsou určeny pouze jako důkaz konceptu. Jakmile se rozhodnete, že chcete mít asynchronní a událostně řízenou komunikaci, jak je vysvětleno v aktuální části, měli byste zvolit produkt služby Service Bus, který nejlépe vyhovuje vašim potřebám pro produkční prostředí.
Události integrace
Události integrace se používají k přenesení stavu domény do synchronizace napříč několika mikroslužbami nebo externími systémy. Tato funkce se provádí publikováním událostí integrace mimo mikroslužbu. Když je událost publikovaná do více mikroslužeb přijímače (do tolika mikroslužeb, kolik se přihlásí k odběru události integrace), příslušná obslužná rutina události v každé mikroslužbě příjemce tuto událost zpracuje.
Událost integrace je v podstatě třída uchovávání dat, jak je znázorněno v následujícím příkladu:
public class ProductPriceChangedIntegrationEvent : IntegrationEvent
{
public int ProductId { get; private set; }
public decimal NewPrice { get; private set; }
public decimal OldPrice { get; private set; }
public ProductPriceChangedIntegrationEvent(int productId, decimal newPrice,
decimal oldPrice)
{
ProductId = productId;
NewPrice = newPrice;
OldPrice = oldPrice;
}
}
Události integrace je možné definovat na úrovni aplikace jednotlivých mikroslužeb, takže jsou oddělené od jiných mikroslužeb způsobem srovnatelným s tím, jak jsou modely ViewModel definovány na serveru a klientovi. Nedoporučuje se sdílení společné knihovny událostí integrace napříč několika mikroslužbami; tím by se tyto mikroslužby propojí s jednou knihovnou dat definice událostí. Nechcete to udělat ze stejných důvodů, že nechcete sdílet společný doménový model napříč několika mikroslužbami: mikroslužby musí být zcela autonomní. Další informace najdete v tomto blogovém příspěvku o množství dat, která se mají vložit do událostí. Dávejte pozor, abyste to příliš neprobrali, protože tento další blogový příspěvek popisuje problémové zprávy, které můžou vést k nedostatku dat. Váš návrh událostí by měl být "správný" pro potřeby jejich spotřebitelů.
Mezi mikroslužbami byste měli sdílet jenom několik druhů knihoven. Jednou z knihoven, které jsou konečnými bloky aplikací, jako je rozhraní API klienta služby Event Bus, jako v eShopOnContainers. Další je knihovny, které tvoří nástroje, které lze také sdílet jako komponenty NuGet, jako jsou serializátory JSON.
Sběrnice událostí
Sběrnice událostí umožňuje komunikaci mezi mikroslužbami ve stylu publikování a odběru, aniž by bylo nutné, aby si komponenty navzájem explicitně uvědomily, jak je znázorněno na obrázku 6–19.
Obrázek 6–19 Publikování a přihlášení k odběru základů pomocí sběrnice událostí
Výše uvedený diagram ukazuje, že mikroslužba A se publikuje do služby Event Bus, která distribuuje odběr mikroslužeb B a C, aniž by vydavatel potřeboval znát odběratele. Sběrnice událostí souvisí se vzorem Pozorovatel a vzorem publikování a odběru.
Vzor pozorovatele
Ve vzoru Pozorovatel váš primární objekt (známý jako Pozorovatelný) upozorní ostatní zúčastněné objekty (označované jako Pozorovatelé) s relevantními informacemi (událostmi).
Model Publikování/přihlášení k odběru (Pub/Sub)
Účel vzoru Publikování/přihlášení k odběru je stejný jako vzor pozorovatele: Chcete upozornit ostatní služby, když se budou provádět určité události. Mezi vzory Pozorovatel a Pub/Sub je ale důležitý rozdíl. Ve vzoru pozorovatele se vysílání provádí přímo z pozorovatelného až po pozorovatele, takže se vzájemně "znají". Pokud ale používáte vzor Pub/Sub, existuje třetí komponenta, která se nazývá zprostředkovatel nebo zprostředkovatel zpráv nebo sběrnice událostí, která je známa vydavatelem i odběratelem. Při použití vzoru Pub/Sub vydavatele a předplatitelé jsou proto přesně odděleny díky zmíněné sběrnici událostí nebo zprostředkovateli zpráv.
Středník nebo sběrnice událostí
Jak dosáhnete anonymizy mezi vydavatelem a předplatitelem? Snadným způsobem je nechat prostředníka, aby se postaral o veškerou komunikaci. Sběrnice událostí je jedním z takových prostředníků.
Sběrnice událostí se obvykle skládá ze dvou částí:
Abstrakce nebo rozhraní.
Jedna nebo více implementací.
Na obrázku 6–19 vidíte, jak z hlediska aplikace není sběrnice událostí nic víc než kanál Pub/Sub. Způsob implementace této asynchronní komunikace se může lišit. Může mít více implementací, abyste mezi nimi mohli přepínat v závislosti na požadavcích prostředí (například produkční a vývojové prostředí).
Na obrázku 6–20 můžete vidět abstrakci sběrnice událostí s několika implementacemi založenými na technologiích zasílání zpráv infrastruktury, jako je RabbitMQ, Azure Service Bus nebo jiný zprostředkovatel událostí nebo zpráv.
Obrázek 6–20 Několik implementací sběrnice událostí
Je dobré mít sběrnici událostí definovanou prostřednictvím rozhraní, aby ji bylo možné implementovat s několika technologiemi, jako je RabbitMQ, Azure Service Bus nebo jiné. A jak už jsme zmínili dříve, použití vlastních abstrakcí (rozhraní sběrnice událostí) je dobré pouze v případě, že potřebujete základní funkce sběrnice událostí podporované abstrakcemi. Pokud potřebujete bohatší funkce služby Service Bus, měli byste místo vlastních abstrakcí pravděpodobně použít rozhraní API a abstrakce poskytované upřednostňovanou sběrnici komerčních služeb.
Definování rozhraní sběrnice událostí
Začněme nějakým kódem implementace pro rozhraní sběrnice událostí a možnými implementacemi pro účely průzkumu. Rozhraní by mělo být obecné a jednoduché, jako v následujícím rozhraní.
public interface IEventBus
{
void Publish(IntegrationEvent @event);
void Subscribe<T, TH>()
where T : IntegrationEvent
where TH : IIntegrationEventHandler<T>;
void SubscribeDynamic<TH>(string eventName)
where TH : IDynamicIntegrationEventHandler;
void UnsubscribeDynamic<TH>(string eventName)
where TH : IDynamicIntegrationEventHandler;
void Unsubscribe<T, TH>()
where TH : IIntegrationEventHandler<T>
where T : IntegrationEvent;
}
Metoda Publish
je jednoduchá. Sběrnice událostí vysílá událost integrace předanou do jakékoli mikroslužby nebo dokonce externí aplikaci, která se k odběru této události přihlásila. Tuto metodu používá mikroslužba, která událost publikuje.
Metody Subscribe
(v závislosti na argumentech můžete mít několik implementací) používají mikroslužby, které chtějí přijímat události. Tato metoda má dva argumenty. První je integrační událost pro přihlášení k odběru (IntegrationEvent
). Druhým argumentem je obslužná rutina události integrace (nebo metoda zpětného volání), která IIntegrationEventHandler<T>
má být provedena, když příjemce mikroslužba získá tuto zprávu události integrace.
Další materiály
Některá řešení pro zasílání zpráv připravená pro produkční prostředí:
Azure Service Bus
https://learn.microsoft.com/azure/service-bus-messaging/NServiceBus
https://particular.net/nservicebusMassTransit
https://masstransit-project.com/