Übung: Senden von Nachrichten zwischen Mikroservices über RabbitMQ

Abgeschlossen

RabbitMQ ist ein zuverlässiger Nachrichtenbroker, der einen flexiblen Nachrichtenaustausch und Warteschlangen bietet. Um in einem .NET Aspire-Projekt Nachrichten über RabbitMQ zu senden und zu empfangen, müssen Sie einen RabbitMQ-Container hinzufügen und dann Code erstellen, der Nachrichten von einem Mikroservice sendet und in einem anderen empfängt.

In dieser Übung senden Sie Nachrichten aus Catalog.API-Projekt an eine Warteschlange. Sie fügen ein neues Projekt für einen Hintergrunddienst hinzu, der diese Nachrichten aus der Warteschlange empfängt und zur Anzeige an das Konsolenprotokoll sendet.

Installieren der erforderlichen Komponenten

Voraussetzungen für .NET Aspire:

  • .NET 8
  • Visual Studio 2022 – Vorschau
  • Docker Desktop oder Podman
  • .NET Aspire-Workload in Visual Studio

Wenn Sie diese Pakete bereits installiert haben, können Sie die Arbeit mit RabbitMQ direkt beginnen.

Installieren von .NET 8

Folgen Sie diesem .NET 8-Link, und wählen Sie das richtige Installationsprogramm für Ihr Betriebssystem aus. Wenn Sie beispielsweise Windows 11 und einen modernen Prozessor verwenden, wählen Sie das x64 .NET 8 SDK für Windows aus.

Führen Sie nach Abschluss des Downloads das Installationsprogramm aus, und folgen Sie den Anweisungen. Führen Sie in einem Terminalfenster den folgenden Befehl aus, um zu überprüfen, ob die Installation erfolgreich war:

dotnet --version

Die Versionsnummer des .NET SDK, das Sie installiert haben, sollte angezeigt werden. Zum Beispiel:

8.0.300-preview.24203.14

Installieren der Vorschauversion von Visual Studio 2022

Folgen Sie diesem Visual Studio 2022 Preview-Link, und wählen Sie Downloadvorschau aus. Führen Sie nach Abschluss des Downloads das Installationsprogramm aus und folgen Sie den Anweisungen.

Installation von Docker Desktop

Folgen Sie diesem Docker Desktop-Link und wählen Sie das richtige Installationsprogramm für Ihr Betriebssystem aus. Führen Sie nach Abschluss des Downloads das Installationsprogramm aus und folgen Sie den Anweisungen. Für die beste Leistung und Kompatibilität verwenden Sie das WSL 2-Back-End.

Öffnen Sie die Docker Desktop-Anwendung und akzeptieren Sie den Servicevertrag.

Installieren der .NET Aspire-Workload in Visual Studio

Installieren Sie die .NET Aspire-Workload mithilfe der .NET CLI:

  1. Öffnen Sie ein Terminal.

  2. Aktualisieren Sie .NET-Workloads mit diesem Befehl:

    dotnet workload update
    

    Es sollte eine Meldung angezeigt werden, dass die Workloads erfolgreich aktualisiert werden.

    No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option.
    Updated advertising manifest microsoft.net.sdk.ios.
    Updated advertising manifest microsoft.net.workload.mono.toolchain.net6.
    Updated advertising manifest microsoft.net.sdk.android.
    Updated advertising manifest microsoft.net.workload.emscripten.net7.
    Updated advertising manifest microsoft.net.workload.emscripten.net6.
    Updated advertising manifest microsoft.net.sdk.macos.
    Updated advertising manifest microsoft.net.workload.emscripten.current.
    Updated advertising manifest microsoft.net.workload.mono.toolchain.current.
    Updated advertising manifest microsoft.net.sdk.maui.
    Updated advertising manifest microsoft.net.workload.mono.toolchain.net7.
    Updated advertising manifest microsoft.net.sdk.maccatalyst.
    Updated advertising manifest microsoft.net.sdk.tvos.
    Updated advertising manifest microsoft.net.sdk.aspire.
    No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option.
    
    Successfully updated workload(s): .
    
  3. Installieren Sie die .NET Aspire-Workload mit diesem Befehl:

    dotnet workload install aspire
    

    Es sollte eine Meldung angezeigt werden, dass die Aspire-Workload installiert ist.

    Installing Aspire.Hosting.Sdk.Msi.x64 ...... Done
    Installing Aspire.ProjectTemplates.Msi.x64 ..... Done
    Installing Aspire.Hosting.Orchestration.win-x64.Msi.x64 ............. Done
    Installing Aspire.Hosting.Msi.x64 ..... Done
    Installing Aspire.Dashboard.Sdk.win-x64.Msi.x64 ....... Done
    
    Successfully installed workload(s) aspire.
    
  4. Stellen Sie sicher, dass die .NET Aspire-Workload mit diesem Befehl installiert wird:

    dotnet workload list
    

    Die Details der .NET Aspire-Workload sollten angezeigt werden.

     Installed Workload Id      Manifest Version      Installation Source
    ---------------------------------------------------------------------------------------------
    aspire                     8.0.0/8.0.100         SDK 8.0.300-preview.24203, VS 17.10.34902.84
    
    Use `dotnet workload search` to find additional workloads to install.
    

Klonen des Projekts

Verwenden Sie git zum Abrufen einer Beispiel-App, die noch keinen Nachrichtenbroker verwendet:

  1. Navigieren Sie in der Befehlszeile zu einem Ordner Ihrer Wahl, in dem Sie mit Code arbeiten können.

  2. Führen Sie den folgenden Befehl aus, um die Beispielanwendung zu klonen:

    git clone -b aspire-rabbitmq  https://github.com/MicrosoftDocs/mslearn-aspire-starter
    

Erstellen des RabbitMQ-Containers

Beginnen Sie mit dem Hinzufügen von RabbitMQ zum App-Hostprojekt. Wenn Sie die Lösung starten, fügt .NET Aspire der App einen RabbitMQ-Container hinzu und übergibt Verweise an die Projekte, die ihn verwenden:

  1. Starten Sie Visual Studio, und wählen Sie Projekt oder Projektmappe öffnen aus.

  2. Navigieren Sie zu dem Ordner, in dem Sie das Projekt geklont haben.

  3. Doppelklicken Sie auf den Ordner Start, und wählen Sie die Projektmappe eShop.rabbitmq.sln und dann Öffnen aus.

  4. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt eShop.AppHost, und wählen Sie Hinzufügen und dann .NET Aspire-Paket aus.

  5. Geben Sie im Suchtextfeld am Ende des vorhandenen Texts RabbitMQ ein.

  6. Wählen Sie das Paket Aspire.Hosting.RabbitMQ aus.

  7. Wählen Sie in der Liste Version die neueste Version 8.0.0 und dann Installieren aus.

  8. Falls das Dialogfeld Vorschau der Änderungen anzeigen erscheint, wählen Sie Übernehmen aus.

  9. Klicken im Dialogfeld Zustimmung zur Lizenz auf Ich stimme zu.

  10. Erweitern Sie im Projektmappen-Explorer das Projekt eShop.AppHost, und doppelklicken Sie dann auf Program.cs.

  11. Suchen Sie folgende Codezeile:

    var builder = DistributedApplication.CreateBuilder(args);
    
  12. Fügen Sie unmittelbar nach diesem Code den folgenden Code hinzu, um einen RabbitMQ-Server zu registrieren:

    var messaging = builder.AddRabbitMQ("messaging");
    
  13. Suchen Sie den folgenden Code, der das Catalog.API-Projekt bei der .NET Aspire-Orchestrierung registriert:

    var catalogApi = builder.AddProject<Catalog_API>("catalog-api")
        .WithReference(catalogDb);
    
  14. Um den RabbitMQ-Dienst an das Catalog.API-Projekt zu übergeben, ändern Sie diesen Code so, dass er folgendem Code entspricht:

    var catalogApi = builder.AddProject<Catalog_API>("catalog-api")
        .WithReference(catalogDb)
        .WithReference(messaging);
    

Hinzufügen von RabbitMQ zum Catalog.API-Projekt

Nun können Sie RabbitMQ im Catalog.API-Projekt installieren und konfigurieren:

  1. Klicken Sie im Projektmappen-Explorer in Visual Studio mit der rechten Maustaste auf das Catalog.API-Projekt, wählen Sie Hinzufügen aus, und wählen Sie dann .NET Aspire-Paket aus.

  2. Geben Sie im Suchtextfeld am Ende des vorhandenen Texts RabbitMQ ein.

  3. Wählen Sie das Paket Aspire.RabbitMQ.Client aus.

  4. Wählen Sie in der Liste Version die neueste Version 8.0.0 und dann Installieren aus.

  5. Falls das Dialogfeld Vorschau der Änderungen anzeigen erscheint, wählen Sie Übernehmen aus.

  6. Klicken im Dialogfeld Zustimmung zur Lizenz auf Ich stimme zu.

  7. Erweitern Sie im Projektmappen-Explorer das Catalog.API-Projekt, und doppelklicken Sie dann auf Program.cs.

  8. Suchen Sie in der Datei Program.cs die folgende Codezeile:

    var builder = WebApplication.CreateBuilder(args);
    
  9. Fügen Sie unmittelbar nach dieser Zeile den folgenden Code hinzu, um die RabbitMQ-Verbindung zu registrieren:

    builder.AddRabbitMQClient("messaging");
    

Senden einer Nachricht an eine RabbitMQ-Warteschlange

Wenn Benutzer:innen Elemente aus dem Katalog anfordern, soll eine Nachricht mit einer Beschreibung der Anforderungsdetails an eine RabbitMQ-Warteschlange gesendet werden. Fügen Sie nun diesen Code hinzu:

  1. Erweitern Sie im Projektmappen-Explorer die OptionCatalog.API > APIs, und doppelklicken Sie dann auf CatalogApi.cs.

  2. Suchen Sie den folgenden Code, der die GetAllItems()-Methode deklariert:

    public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems(
        [AsParameters] PaginationRequest paginationRequest,
        [AsParameters] CatalogServices services)
    {
    
  3. Um Abhängigkeitsinjektion zum Abrufen der Verbindung mit RabbitMQ zu verwenden, ändern Sie den Code so, dass er mit den folgenden Zeilen übereinstimmt:

    public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems(
        [AsParameters] PaginationRequest paginationRequest,
        [AsParameters] CatalogServices services,
        RabbitMQ.Client.IConnection connection)
    {
    
  4. Suchen Sie folgende Codezeile:

    var totalItems = await services.DbContext.CatalogItems
        .LongCountAsync();
    
  5. Fügen Sie unmittelbar nach dieser Zeile den folgenden Code hinzu, um einen RabbitMQ-Messagingkanal zu erstellen:

    var channel = connection.CreateModel();
    
  6. Fügen Sie in der nächsten Zeile den folgenden Code hinzu, um eine Nachrichtenwarteschlange zu erstellen:

    channel.QueueDeclare(queue: "catalogEvents",
                         durable: false,
                         exclusive: false,
                         autoDelete: false,
                         arguments: null);
    
  7. Fügen Sie in der nächsten Zeile den folgenden Code hinzu, um die Nachricht zu senden:

    var body = Encoding.UTF8.GetBytes("Getting all items in the catalog.");
    
    channel.BasicPublish(exchange: string.Empty,
                         routingKey: "catalogEvents",
     					 mandatory: false,
                         basicProperties: null,
                         body: body);
    

Hinzufügen eines Nachrichtenconsumerprojekts

Um Nachrichten aus der RabbitMQ-Warteschlange zu empfangen, erstellen Sie nun ein neues Projekt:

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Projektmappe, zeigen Sie auf Hinzufügen, und wählen Sie anschließend Neues Projekt aus.

  2. Geben Sie im Textfeld Nach Vorlagen suchen die Zeichenfolge Konsole ein.

  3. Wählen Sie die C#-Vorlage für eine Konsolen-App und dann Weiter aus.

  4. Geben Sie im Textfeld Projektname den Namen RabbitConsumer ein, und wählen Sie dann Weiter aus.

  5. Vergewissern Sie sich, dass in der Liste Framework die Option .NET 8.0 ausgewählt ist, und wählen Sie dann Erstellen aus.

  6. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt AppHost, zeigen Sie auf Hinzufügen, und wählen Sie dann Projektreferenz aus.

  7. Vergewissern Sie sich, dass in der Projektliste RabbitConsumer ausgewählt ist, und wählen Sie dann OK aus.

    Screenshot des Hinzufügens eines Verweises auf das AppHost-Projekt, das auf das RabbitConsumer-Projekt verweist

  8. Erweitern Sie im Projektmappen-Explorer das Projekt AppHost, und doppelklicken Sie dann auf Program.cs.

  9. Suchen Sie den folgenden Code:

    builder.AddProject<WebApp>("webapp")
        .WithReference(catalogApi);
    
  10. Fügen Sie unmittelbar nach diesem Code den folgenden Code hinzu, um das Projekt RabbitConsumer der .NET Aspire-Orchestrierung hinzuzufügen:

    builder.AddProject<Projects.RabbitConsumer>("consumers")
        .WithReference(messaging);
    

Konfigurieren des Nachrichtenconsumerprojekts

Damit Sie Nachrichten im neuen Nachrichtenconsumerprojekt empfangen können, müssen Sie es so konfigurieren, dass der RabbitMQ-Hintergrunddienst vom AppHost verwendet wird:

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt RabbitConsumer, und wählen Sie Hinzufügen und dann .NET Aspire-Paket aus.

  2. Geben Sie im Suchtextfeld am Ende des vorhandenen Texts RabbitMQ ein.

  3. Wählen Sie das Paket Aspire.RabbitMQ.Client aus.

  4. Wählen Sie in der Liste Version die neueste Version 8.0.0 und dann Installieren aus.

  5. Falls das Dialogfeld Vorschau der Änderungen anzeigen erscheint, wählen Sie Übernehmen aus.

  6. Klicken im Dialogfeld Zustimmung zur Lizenz auf Ich stimme zu.

  7. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt RabbitConsumer, zeigen Sie auf Hinzufügen, und wählen Sie dann Projektreferenz aus.

  8. Vergewissern Sie sich, dass in der Projektliste eShop.ServiceDefaults ausgewählt ist, und wählen Sie dann OK aus.

    Screenshot des Hinzufügens eines Verweises auf das RabbitConsumer-Projekt, das auf das ServiceDefaults-Projekt verweist

  9. Erweitern Sie im Projektmappen-Explorer das RabbitConsumer-Projekt, und doppelklicken Sie dann auf Program.cs.

  10. Entfernen Sie den gesamten Standardcode, und ersetzen Sie ihn durch die folgenden Zeilen:

    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    
    var builder = Host.CreateApplicationBuilder(args);
    
    builder.AddServiceDefaults();
    
    builder.AddRabbitMQClient("messaging");
    
    var host = builder.Build();
    
    host.Run();
    

    Beachten Sie, dass der Code die .NET Aspire-Orchestrierung verwendet, um dem Consumerprojekt den RabbitMQ-Dienst hinzuzufügen. Sie verwenden diesen Dienst zum Abrufen von Nachrichten.

Empfangen einer RabbitMQ-Nachricht

Um eine Nachricht zu empfangen, müssen Sie eine Integration erstellen, die im Hintergrund ausgeführt wird und auf das Eintreffen von Nachrichten wartet. Verwenden Sie für diese Aufgabe eine BackgroundService-Klasse:

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt RabbitConsumer, zeigen Sie auf Hinzufügen, und wählen Sie dann Klasse aus.

  2. Geben Sie im Textfeld Name die Zeichenfolge CatalogProcessingJob ein, und wählen Sie dann Hinzufügen aus.

  3. Entfernen Sie in der CatalogProcessingJob.cs-Klasse den gesamten Standardcode, und ersetzen Sie ihn durch die folgenden Zeilen:

     namespace RabbitConsumer;
    
    using System.Text;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using RabbitMQ.Client;
    using RabbitMQ.Client.Events;
    
    public class CatalogProcessingJob : BackgroundService
    {
        private readonly ILogger<CatalogProcessingJob> _logger;
        private readonly IConfiguration _config;
        private readonly IServiceProvider _serviceProvider;
        private IConnection? _messageConnection;
        private IModel? _messageChannel;
     	private EventingBasicConsumer consumer;
    
        public CatalogProcessingJob(ILogger<CatalogProcessingJob> logger, IConfiguration config, IServiceProvider serviceProvider, IConnection? messageConnection)
        {
            _logger = logger;
            _config = config;
            _serviceProvider = serviceProvider;
        }
    
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            string queueName = "catalogEvents";
    
            _messageConnection = _serviceProvider.GetRequiredService<IConnection>();
    
            _messageChannel = _messageConnection.CreateModel();
            _messageChannel.QueueDeclare(queue: queueName,
                durable: false,
                exclusive: false,
                autoDelete: false,
                arguments: null);
    
            consumer = new EventingBasicConsumer(_messageChannel);
            consumer.Received += ProcessMessageAsync;
    
            _messageChannel.BasicConsume(queue:  queueName,
                autoAck: true, 
                consumer: consumer);
    
            return Task.CompletedTask;
        }
    
        public override async Task StopAsync(CancellationToken cancellationToken)
        {
            await base.StopAsync(cancellationToken);
            consumer.Received -= ProcessMessageAsync;
            _messageChannel?.Dispose();
        }
    
        private void ProcessMessageAsync(object? sender, BasicDeliverEventArgs args)
        {
    
            string messagetext = Encoding.UTF8.GetString(args.Body.ToArray());
            _logger.LogInformation("All products retrieved from the catalog at {now}. Message Text: {text}", DateTime.Now, messagetext);
    
            var message = args.Body;
        }
    }
    
  4. Doppelklicken Sie im Projektmappen-Explorer im RabbitConsumer-Projekt auf Program.cs.

  5. Suchen Sie den folgenden Code:

    builder.AddRabbitMQClient("messaging");
    
  6. Fügen Sie unmittelbar nach dieser Zeile den folgenden Code hinzu:

    builder.Services.AddHostedService<CatalogProcessingJob>();
    

Testen der Lösung

Testen Sie nun den RabbitMQ-Hintergrunddienst und die Microservices, die Nachrichten senden und empfangen:

  1. Drücken Sie in Visual Studio F5, um die App im Debugmodus zu starten, oder wählen SieDebuggen > Debuggen starten aus.

  2. Wenn die Meldung Docker Desktop starten angezeigt wird, wählen Sie Ja aus. Die App wird gestartet und zeigt das .NET Aspire-Dashboard auf einer Browserregisterkarte an.

  3. Beachten Sie, dass die Liste der Ressourcen auf dem .NET Aspire-Dashboard einen neuen Container mit dem Messaging enthält. Die Quelle enthält rabbitmq:3. Dieser Container führt den RabbitMQ-Nachrichtenbroker aus.

    Screenshot eines RabbitMQ-Containers auf dem .NET Aspire-Dashboard

  4. Wählen Sie im Navigationsbereich auf der linken Seite die Option Konsole aus.

  5. Wählen Sie in der Liste Ressource auswählen die Option Messaging aus. Auf der Seite werden die Konsolenprotokolle für den RabbitMQ-Broker angezeigt. Beachten Sie, dass die letzten Nachrichten darauf hindeuten, dass der Start von RabbitMQ abgeschlossen und eine Verbindung akzeptiert wurde. Diese Verbindung stammt aus dem empfangenden RabbitConsumer-Projekt.

  6. Wählen Sie im Navigationsbereich auf der linken Seite die Option Ressourcen aus.

  7. Wählen Sie in der Zeile für das webapp-Projekt in der Spalte Endpunkte einen der Links aus. Die Homepage von Northern Traders wird geöffnet, auf der der Produktkatalog angezeigt wird. Diese Seite sendet eine Nachricht an die RabbitMQ-Warteschlange.

    Screenshot des Zugriffs auf den Endpunkt des WebApp-Projekts über das .NET Aspire-Dashboard

  8. Wechseln Sie zurück zum .NET Aspire-Dashboard. Wählen Sie im Navigationsbereich auf der linken Seite die Option Konsole aus.

  9. Wählen Sie in der Liste Ressource auswählen die Option Messaging aus. Beachten Sie, dass RabbitMQ eine zweite Verbindung akzeptiert hat. Diese Verbindung stammt aus dem Catalog.API-Projekt.

  10. Wählen Sie in der Liste Ressource auswählen die Option Consumer aus. Dies ist das Protokoll für das RabbitConsumer-Projekt. Der letzte Eintrag enthält die Meldung „Alle Elemente im Katalog abrufen“. Diese Nachricht wurde von RabbitMQ abgerufen und protokolliert.

    Screenshot der von der RabbitMQ-Warteschlange abgerufenen Nachricht in den Konsolenprotokollen für das Consumerprojekt