Partager via


Implémentation d’un bus d’événements avec RabbitMQ pour l’environnement de développement ou de test

Conseil / Astuce

Ce contenu est un extrait du livre électronique 'Architecture des microservices .NET pour les applications .NET conteneurisées', disponible sur .NET Docs ou en tant que PDF téléchargeable gratuitement, lisible hors ligne.

Architecture de microservices .NET pour les applications .NET conteneurisées - vignette de couverture du livre électronique.

Nous devons commencer par dire que si vous créez votre bus d’événements personnalisé basé sur RabbitMQ exécuté dans un conteneur, comme l’application eShopOnContainers le fait, elle doit être utilisée uniquement pour vos environnements de développement et de test. Ne l’utilisez pas pour votre environnement de production, sauf si vous le créez dans le cadre d’un bus de service prêt pour la production, comme décrit dans la section Ressources supplémentaires ci-dessous. Un bus d’événements personnalisé simple peut manquer de nombreuses fonctionnalités critiques prêtes pour la production qu’a un bus de service commercial.

L’une des implémentations personnalisées de bus d’événements dans eShopOnContainers est essentiellement une bibliothèque utilisant l’API RabbitMQ. (Il existe une autre implémentation basée sur Azure Service Bus.)

L’implémentation de bus d’événements avec RabbitMQ permet aux microservices de s’abonner à des événements, de publier des événements et de recevoir des événements, comme illustré dans la figure 6-21.

Diagramme montrant RabbitMQ entre l’expéditeur du message et le récepteur de messages.

Figure 6-21. Implémentation RabbitMQ d’un bus d’événements

RabbitMQ fonctionne comme intermédiaire entre l’éditeur de messages et les abonnés pour gérer la distribution. Dans le code, la classe EventBusRabbitMQ implémente l’interface IEventBus générique. Cette implémentation est basée sur l’injection de dépendances afin de pouvoir passer de cette version de développement/test à une version de production.

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

L’implémentation RabbitMQ d’un exemple de bus d’événements de développement/test est du code standard. Il doit gérer la connexion au serveur RabbitMQ et fournir du code pour la publication d’un événement de message dans les files d’attente. Il doit également implémenter un dictionnaire de collections de gestionnaires d’événements d’intégration pour chaque type d’événement ; ces types d’événements peuvent avoir une instanciation différente et des abonnements différents pour chaque microservice récepteur, comme illustré dans la figure 6-21.

Implémentation d’une méthode de publication simple avec RabbitMQ

Le code suivant est une version simplifiée d’une implémentation de bus d’événements pour RabbitMQ, afin de présenter l’ensemble du scénario. Vous ne gérez pas vraiment la connexion de cette façon. Pour voir l’implémentation complète, consultez le code réel dans le dépôt 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);
       }
    }
}

Le code réel de la méthode Publish dans l’application eShopOnContainers est amélioré à l’aide d’une stratégie de nouvelle tentative Polly , qui retente la tâche parfois si le conteneur RabbitMQ n’est pas prêt. Ce scénario peut se produire lorsque docker-compose démarre les conteneurs ; par exemple, le conteneur RabbitMQ peut démarrer plus lentement que les autres conteneurs.

Comme mentionné précédemment, il existe de nombreuses configurations possibles dans RabbitMQ. Ce code doit donc être utilisé uniquement pour les environnements de développement/test.

Implémentation du code d’abonnement avec l’API RabbitMQ

Comme pour le code de publication, le code suivant est une simplification de la partie de l’implémentation de bus d’événements pour RabbitMQ. Là encore, vous n’avez généralement pas besoin de le modifier, sauf si vous l’améliorez.

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

Chaque type d’événement a un canal associé pour obtenir des événements à partir de RabbitMQ. Vous pouvez ensuite avoir autant de gestionnaires d’événements par canal et par type d’événement que nécessaire.

La méthode Subscribe accepte un objet IIntegrationEventHandler, qui est semblable à une méthode de rappel dans le microservice actuel, ainsi que son objet IntegrationEvent associé. Le code ajoute ensuite ce gestionnaire d’événements à la liste des gestionnaires d’événements que chaque type d’événement d’intégration peut avoir par microservice client. Si le code client n’a pas déjà été abonné à l’événement, le code crée un canal pour le type d’événement afin qu’il puisse recevoir des événements dans un style Push de RabbitMQ lorsque cet événement est publié à partir d’un autre service.

Comme mentionné ci-dessus, le bus d’événements implémenté dans eShopOnContainers n’a qu’un but éducatif, car il gère uniquement les principaux scénarios, de sorte qu’il n’est pas prêt pour la production.

Pour les scénarios de production, vérifiez les ressources supplémentaires ci-dessous, spécifiques à RabbitMQ et la section Implémentation de la communication basée sur les événements entre les microservices .

Ressources supplémentaires

Solution prête pour la production avec prise en charge de RabbitMQ.