Sdílet prostřednictvím


Implementace komunikace založené na událostech mezi mikroslužbami (události integrace)

Návod

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.

eBook o architektuře mikroslužeb .NET pro kontejnerizované aplikace .NET, miniatura na obálce.

Jak bylo popsáno dříve, když používáte komunikaci založenou na událostech, mikroslužba publikuje událost při významné události, 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řesahují základní trvalost a sběrnici událostí, takže je potřeba zpracovat idempotenci. 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.

Diagram asynchronní komunikace řízené událostmi pomocí sběrnice událostí

Obrázek 6–18 Komunikace řízená událostmi na základě sběrnice 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, zprostředkovatel zpráv, pracuje 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, stojí za to vyhodnotit další servisní autobusy, ať už komerční nebo opensourcové, jako jsou NServiceBus, MassTransit a Brighter. V tomto případě by abstrakce a rozhraní API, které se mají použít, obvykle byly přímo ty, které poskytují tyto služební sběrnice vysoké úrovně, místo vašich 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á společností Particular Software).

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á.

Je třeba zopakovat, že ukázkové abstrakce sběrnice událostí a implementace, které jsou prezentovány v ukázce eShopOnContainers, jsou určeny pouze jako ukázka 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 jsou knihovny, 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.

Diagram znázorňující základní vzor publikování/přihlášení k odběru

Obrázek 6–19 Základy publikování/odběru událostí prostřednictvím sběrnice událostí

Výše uvedený diagram ukazuje, že mikroslužba A publikuje do Event Bus, která distribuuje je předplatitelům mikroslužeb B a C, aniž by musel znát odběratele. Sběrnice událostí souvisí se vzorem Pozorovatel a vzorem vydavatel-předplatitel.

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 ze subjektu k pozorovatelům, 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.

Prostř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í slouží jako jeden 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.

Diagram znázorňující přidání abstraktní vrstvy sběrnice událostí

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 Service Bus, měli byste spíše použít rozhraní API a abstrakce poskytované vaší preferovanou komerční sběrnicí služeb namísto vlastních abstrakcí.

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í bude vysílat integrační událost předanou jí do jakékoli mikroslužby nebo dokonce externí aplikace, která je přihlášená k odběru této události. 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í), IIntegrationEventHandler<T>, která má být provedena, když mikroslužba příjemce získá tuto zprávu události integrace.

Dodatečné zdroje

Některá řešení pro zasílání zpráv připravená pro produkční prostředí: