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


Eseménybusz megvalósítása a RabbitMQ-val a fejlesztési vagy tesztelési környezethez

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.

Először is azt kell mondanunk, hogy ha egy tárolóban futó RabbitMQ alapján hozza létre az egyéni eseménybuszt, ahogyan az eShopOnContainers alkalmazás teszi, akkor csak a fejlesztési és tesztelési környezetekhez kell használni. Ne használja az éles környezethez, hacsak nem egy éles üzemre kész service bus részeként készíti el az alábbi További erőforrások szakaszban leírtak szerint. Előfordulhat, hogy egy egyszerű egyéni eseménybusz számos, éles üzemre kész kritikus funkciót tartalmaz, amelyekkel egy kereskedelmi szolgáltatásbusz rendelkezik.

Az eShopOnContainersben az event bus egyéni implementációinak egyike alapvetően egy, a RabbitMQ API-t használó kódtár. (Az Azure Service Buson alapuló másik implementáció is létezik.)

Az Event Bus RabbitMQ-val történő implementálása lehetővé teszi, hogy a mikroszolgáltatások feliratkozzanak az eseményekre, eseményeket tegyenek közzé és fogadják az eseményeket a 6–21. ábrán látható módon.

Ábra a RabbitMQ-ról az üzenet feladója és az üzenet fogadója között.

6–21. ábra. Eseménybusz RabbitMQ implementálása

A RabbitMQ közvetítőként működik az üzenet közzétevője és az előfizetők között a terjesztés kezeléséhez. A kódban az EventBusRabbitMQ osztály implementálja az általános IEventBus-felületet. Ez az implementáció függőséginjektáláson alapul, így ebből a fejlesztési/tesztelési verzióból egy éles verzióra válthat.

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

A minta dev/test event bus RabbitMQ implementációja egy sablonkód. Kezelnie kell a RabbitMQ-kiszolgálóval való kapcsolatot, és meg kell adnia egy üzenetesemény üzenetsorokon való közzétételéhez szükséges kódot. Emellett az integrációs eseménykezelők gyűjteményeinek szótárát is implementálnia kell az egyes eseménytípusokhoz; ezek az eseménytípusok különböző példányokkal és előfizetésekkel rendelkezhetnek az egyes fogadó mikroszolgáltatásokhoz, ahogyan az a 6–21. ábrán látható.

Egyszerű közzétételi módszer implementálása a RabbitMQ-val

Az alábbi kód a RabbitMQ eseménybusz-implementációjának egyszerűsített verziója, a teljes forgatókönyv bemutatásához. Nem igazán kezeli a kapcsolatot így. A teljes implementáció megtekintéséhez tekintse meg a tényleges kódot a dotnet-architecture/eShopOnContainers adattárban.

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);
       }
    }
}

Az eShopOnContainers alkalmazásban a Publish metódus tényleges kódját egy Polly újrapróbálkozási szabályzattal fejlesztjük, amely bizonyos esetekben újrapróbálkozza a feladatot, ha a RabbitMQ-tároló nem áll készen. Ez a forgatókönyv akkor fordulhat elő, ha a docker-compose elindítja a tárolókat; Előfordulhat például, hogy a RabbitMQ-tároló lassabban indul el, mint a többi tároló.

Ahogy korábban említettük, a RabbitMQ-ban számos lehetséges konfiguráció létezik, ezért ezt a kódot csak fejlesztői/tesztelési környezetekhez szabad használni.

Az előfizetési kód implementálása a RabbitMQ API-val

A közzétételi kódhoz hasonlóan a következő kód a RabbitMQ event bus implementációjának egy részének egyszerűsítése. Ismét, akkor általában nem kell módosítania, ha nem javítja azt.

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>();
    }
}

Minden eseménytípushoz tartozik egy kapcsolódó csatorna, amely lekéri az eseményeket a RabbitMQ-ból. Ezután csatornánként és eseménytípusonként tetszőleges számú eseménykezelőt használhat.

A Feliratkozás metódus egy IIntegrationEventHandler objektumot fogad el, amely olyan, mint egy visszahívási módszer az aktuális mikroszolgáltatásban, valamint a kapcsolódó IntegrationEvent objektumot. A kód ezután hozzáadja ezt az eseménykezelőt azoknak az eseménykezelőknek a listájához, amelyeket az egyes integrációs eseménytípusok ügyfél-mikroszolgáltatásonként használhatnak. Ha az ügyfélkód még nem iratkozott fel az eseményre, a kód létrehoz egy csatornát az eseménytípushoz, hogy leküldéses stílusban fogadhassa az eseményeket a RabbitMQ-tól, amikor az eseményt bármely más szolgáltatásból közzéteszik.

Mint fentebb említettük, az eShopOnContainersben implementált eseménybusznak csak oktatási célja van, mivel csak a fő forgatókönyveket kezeli, így nem áll készen a gyártásra.

Éles forgatókönyvek esetén tekintse át az alábbi, a RabbitMQ-ra vonatkozó további erőforrásokat, valamint a mikroszolgáltatások közötti eseményalapú kommunikáció implementálását.

További erőforrások

Éles üzemre kész megoldás a RabbitMQ támogatásával.