Implementace sběrnice událostí pomocí RabbitMQ pro vývojové nebo testovací prostředí

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.

Architektura mikroslužeb .NET pro kontejnerizované eBooky aplikací .NET

Měli bychom začít tím, že pokud vytvoříte vlastní sběrnici událostí založenou na RabbitMQ spuštěném v kontejneru, jak to dělá aplikace eShopOnContainers, měla by se používat pouze pro vývojová a testovací prostředí. Nepoužívejte ho pro produkční prostředí, pokud ho nevytáčíte jako součást sběrnice service bus připravené pro produkční prostředí, jak je popsáno v části Další zdroje informací níže. V jednoduché vlastní sběrnici událostí může chybět mnoho důležitých funkcí připravených pro produkční prostředí, které má komerční sběrnice služeb.

Jedna z vlastních implementací sběrnice událostí v eShopOnContainers je v podstatě knihovna využívající rozhraní RabbitMQ API. (Existuje další implementace založená na službě Azure Service Bus.)

Implementace sběrnice událostí pomocí RabbitMQ umožňuje mikroslužbám odebírat události, publikovat události a přijímat události, jak je znázorněno na obrázku 6–21.

Diagram znázorňující RabbitMQ mezi odesílatelem zprávy a příjemcem zprávy

Obrázek 6–21 RabbitMQ implementace sběrnice událostí

RabbitMQ funguje jako zprostředkovatel mezi vydavatelem zpráv a odběrateli pro zpracování distribuce. V kódu EventBusRabbitMQ třída implementuje obecné IEventBus rozhraní. Tato implementace je založená na injektáži závislostí, abyste ji mohli prohodit z této verze pro vývoj/testování na produkční verzi.

public class EventBusRabbitMQ : IEventBus, IDisposable
{
    // Implementation using RabbitMQ API
    //...
}

Implementace RabbitMQ ukázkové sběrnice událostí pro vývoj/testování je často používaný kód. Musí zpracovat připojení k serveru RabbitMQ a poskytnout kód pro publikování události zprávy do front. Musí také implementovat slovník kolekcí obslužných rutin událostí integrace pro každý typ události; tyto typy událostí můžou mít jinou instanci a různá předplatná pro každou mikroslužbu příjemce, jak je znázorněno na obrázku 6–21.

Implementace jednoduché metody publikování pomocí RabbitMQ

Následující kód je zjednodušená verze implementace sběrnice událostí pro RabbitMQ, která představuje celý scénář. Tímto způsobem připojení nezvládáte. Pokud chcete zobrazit úplnou implementaci, podívejte se na skutečný kód v úložišti dotnet-architecture/eShopOnContainers .

public class EventBusRabbitMQ : IEventBus, IDisposable
{
    // Member objects and other methods ...
    // ...

    public void Publish(IntegrationEvent @event)
    {
        var eventName = @event.GetType().Name;
        var factory = new ConnectionFactory() { HostName = _connectionString };
        using (var connection = factory.CreateConnection())
        using (var channel = connection.CreateModel())
        {
            channel.ExchangeDeclare(exchange: _brokerName,
                type: "direct");
            string message = JsonConvert.SerializeObject(@event);
            var body = Encoding.UTF8.GetBytes(message);
            channel.BasicPublish(exchange: _brokerName,
                routingKey: eventName,
                basicProperties: null,
                body: body);
       }
    }
}

Skutečný kód metody Publish v aplikaci eShopOnContainers je vylepšen pomocí zásady opakování Polly , která opakuje úlohu několikrát v případě, že kontejner RabbitMQ není připravený. K tomuto scénáři může dojít, když docker-compose spouští kontejnery; Například kontejner RabbitMQ může být pomalejší než ostatní kontejnery.

Jak už bylo zmíněno dříve, v RabbitMQ existuje mnoho možných konfigurací, takže tento kód by se měl používat jenom pro vývojová/testovací prostředí.

Implementace kódu předplatného pomocí rozhraní RabbitMQ API

Stejně jako u kódu publikování je následující kód zjednodušením části implementace sběrnice událostí pro RabbitMQ. Znovu, obvykle ho nemusíte měnit, pokud ho nevylepšujete.

public class EventBusRabbitMQ : IEventBus, IDisposable
{
    // Member objects and other methods ...
    // ...

    public void Subscribe<T, TH>()
        where T : IntegrationEvent
        where TH : IIntegrationEventHandler<T>
    {
        var eventName = _subsManager.GetEventKey<T>();

        var containsKey = _subsManager.HasSubscriptionsForEvent(eventName);
        if (!containsKey)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            using (var channel = _persistentConnection.CreateModel())
            {
                channel.QueueBind(queue: _queueName,
                                    exchange: BROKER_NAME,
                                    routingKey: eventName);
            }
        }

        _subsManager.AddSubscription<T, TH>();
    }
}

Každý typ události má související kanál pro získání událostí z RabbitMQ. Podle potřeby pak můžete mít tolik obslužných rutin událostí na kanál a typ události.

Metoda Subscribe přijímá IIntegrationEventHandler objekt, který je jako metoda zpětného volání v aktuální mikroslužbě a jeho související IntegrationEvent objektu. Kód pak tuto obslužnou rutinu události přidá do seznamu obslužných rutin událostí, které každý typ události integrace může mít pro jednotlivé klientské mikroslužby. Pokud se kód klienta ještě nepřihlásil k odběru události, vytvoří kód kanál pro typ události, aby mohl přijímat události ve stylu nabízení z RabbitMQ, když je tato událost publikována z jakékoli jiné služby.

Jak už bylo zmíněno výše, sběrnice událostí implementovaná v eShopOnContainers má pouze vzdělávací účel, protože zpracovává pouze hlavní scénáře, takže není připravená pro produkci.

V případě produkčních scénářů zkontrolujte níže uvedené další zdroje, specifické pro RabbitMQ a implementaci komunikace založené na událostech mezi mikroslužbami .

Další materiály

Řešení připravené pro produkční prostředí s podporou RabbitMQ.