演習 - RabbitMQ を使用してマイクロサービス間でメッセージを送信する

完了

RabbitMQ は、柔軟なメッセージング交換とキューを提供する信頼性の高いメッセージ ブローカーです。 .NET Aspire プロジェクトで RabbitMQ を介してメッセージを送受信するには、RabbitMQ コンテナーを追加し、1 つのマイクロサービスからメッセージを送信して別のマイクロサービスで受信するコードを作成する必要があります。

この演習では、Catalog.API プロジェクトからキューにメッセージを送信します。 キューからこれらのメッセージを受信し、コンソール ログに送信して表示する新しいバックグラウンド サービス プロジェクトを追加します。

必須コンポーネントのインストール

.NET Aspire の前提条件は次のとおりです。

  • .NET 8
  • Visual Studio 2022 Preview
  • Docker Desktop または Podman
  • Visual Studio の .NET Aspire ワークロード

これらのパッケージが既にインストールされている場合は、先に進んで RabbitMQ の操作を開始できます。

.NET 8 をインストールする

この .NET 8 のリンクに従って、オペレーティング システムに適したインストーラーを選択します。 たとえば、Windows 11 と最新のプロセッサを使用している場合は、x64 .NET 8 SDK for Windows を選択します。

ダウンロードが完了した後、インストーラーを実行し、指示に従います。 ターミナル ウィンドウで、次のコマンドを実行して、インストールが成功したことを確認します。

dotnet --version

インストールした .NET SDK のバージョン番号が表示されるはずです。 次に例を示します。

8.0.300-preview.24203.14

Visual Studio 2022 Preview をインストールする

この Visual Studio 2022 Preview のリンクに従って、[プレビューのダウンロード] を選択します。 ダウンロードが完了した後、インストーラーを実行し、指示に従います。

Docker Desktop のインストール

この Docker Desktop のリンクに従って、オペレーティング システムに適したインストーラーを選択します。 ダウンロードが完了した後、インストーラーを実行し、指示に従います。 パフォーマンスと互換性を最大限に高めるには、WSL 2 バックエンドを使用します。

Docker Desktop アプリケーションを開き、サービス契約に同意します。

Visual Studio に .NET Aspire ワークロードをインストールする

.NET CLI を使用して、.NET Aspire ワークロードをインストールします。

  1. ターミナルを開きます。

  2. 次のコマンドを使用して .NET ワークロードを更新します。

    dotnet workload update
    

    ワークロードが正常に更新されたことを示すメッセージが表示されるはずです。

    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. 次のコマンドを使用して、.NET Aspire ワークロードをインストールします。

    dotnet workload install aspire
    

    Aspire ワークロードがインストールされたことを示すメッセージが表示されるはずです。

    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. 次のコマンドを使用して、.NET Aspire ワークロードがインストールされていることを確認します。

    dotnet workload list
    

    .NET Aspire ワークロードの詳細が表示されます。

     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.
    

プロジェクトを複製する

メッセージ ブローカーをまだ使用していないサンプル アプリを取得するために git を使用してみましょう。

  1. コマンド ラインで、コードを操作できる任意のフォルダーを参照します。

  2. 次のコマンドを実行して、サンプル アプリケーションをクローンします。

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

RabbitMQ コンテナーを作成する

まず、RabbitMQ をアプリ ホスト プロジェクトに追加します。 ソリューションを開始すると、.NET Aspire によって RabbitMQ コンテナーがアプリに追加され、それを使用するプロジェクトへの参照が渡されます。

  1. Visual Studio を開き、[プロジェクトやソリューションを開く] を選択します。

  2. プロジェクトをクローンしたフォルダーに移動します。

  3. start フォルダーをダブルクリックし、eShop.rabbitmq.sln ソリューションを選択して、[開く] を選択します。

  4. ソリューション エクスプローラーeShop.AppHost プロジェクトを右クリックし、[追加] を選び、[.NET Aspire パッケージ] を選びます。

  5. 検索テキストボックスの既存のテキストの末尾に「RabbitMQ」と入力します。

  6. Aspire.Hosting.RabbitMQ パッケージを選びます。

  7. [バージョン] 一覧で最新の 8.0.0 バージョンを選び、[インストール] を選びます。

  8. [変更のプレビュー] ダイアログが表示された場合は、[適用] を選びます。

  9. [ライセンスの同意] ウィンドウで、[同意する] を選択します。

  10. ソリューション エクスプローラーで、eShop.AppHost を展開し、Program.cs をダブルクリックします。

  11. 次のコード行を検索します。

    var builder = DistributedApplication.CreateBuilder(args);
    
  12. そのコードの直後に RabbitMQ サーバーを登録するには、次のコードを追加します。

    var messaging = builder.AddRabbitMQ("messaging");
    
  13. 次のコードを見つけます。このコードは、.NET Aspire オーケストレーション用の Catalog.API プロジェクトを登録します。

    var catalogApi = builder.AddProject<Catalog_API>("catalog-api")
        .WithReference(catalogDb);
    
  14. RabbitMQ サービスを Catalog.API プロジェクトに渡すには、次のコードに一致するようにそのコードを変更します。

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

Catalog.API プロジェクトに RabbitMQ を追加する

これで、Catalog.API プロジェクトに RabbitMQ をインストールして構成できるようになりました。

  1. Visual Studio のソリューション エクスプローラーCatalog.API プロジェクトを右クリックし、[追加] を選んでから、[.NET Aspire パッケージ] を選びます。

  2. 検索テキストボックスの既存のテキストの末尾に「RabbitMQ」と入力します。

  3. Aspire.RabbitMQ.Client パッケージを選択します。

  4. [バージョン] 一覧で最新の 8.0.0 バージョンを選び、[インストール] を選びます。

  5. [変更のプレビュー] ダイアログが表示された場合は、[適用] を選びます。

  6. [ライセンスの同意] ウィンドウで、[同意する] を選択します。

  7. ソリューション エクスプローラーで、Catalog.API プロジェクトを展開し、Program.cs をダブルクリックします。

  8. Program.cs ファイルで、次のコード行を見つけます。

    var builder = WebApplication.CreateBuilder(args);
    
  9. その行の直後に RabbitMQ 接続を登録するには、次のコードを追加します。

    builder.AddRabbitMQClient("messaging");
    

RabbitMQ キューにメッセージを送信する

ユーザーがカタログ内の項目を要求したときに、要求の詳細を説明するメッセージを RabbitMQ キューに送信します。 そのコードをここで追加しましょう。

  1. ソリューション エクスプローラーCatalog.API > Apis を展開し、CatalogApi.cs をダブルクリックします。

  2. 次のコードを見つけます。ここでは、GetAllItems() メソッドを宣言しています。

    public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems(
        [AsParameters] PaginationRequest paginationRequest,
        [AsParameters] CatalogServices services)
    {
    
  3. 依存関係の挿入を使用して RabbitMQ への接続を取得するには、次の行に一致するようにコードを変更します。

    public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems(
        [AsParameters] PaginationRequest paginationRequest,
        [AsParameters] CatalogServices services,
        RabbitMQ.Client.IConnection connection)
    {
    
  4. 次のコード行を検索します。

    var totalItems = await services.DbContext.CatalogItems
        .LongCountAsync();
    
  5. その行の直後に RabbitMQ メッセージング チャネルを作成するには、次のコードを追加します。

    var channel = connection.CreateModel();
    
  6. 次の行で、メッセージ キューを作成するために、次のコードを追加します。

    channel.QueueDeclare(queue: "catalogEvents",
                         durable: false,
                         exclusive: false,
                         autoDelete: false,
                         arguments: null);
    
  7. 次の行で、メッセージを送信するために、次のコードを追加します。

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

メッセージ コンシューマー プロジェクトを追加する

RabbitMQ キューからメッセージを受信するために、新しいプロジェクトを作成しましょう。

  1. ソリューション エクスプローラーで、ソリューションを右クリックし、[追加] をポイントして、[新しいプロジェクト] をクリックします。

  2. [テンプレートの検索] テキストボックスに「Console」と入力します。

  3. C# コンソール アプリ テンプレートを選択し、[次へ] を選択します。

  4. [プロジェクト名] テキストボックスに「RabbitConsumer」と入力し、[次へ] を選択します。

  5. フレームワークの一覧で、.NET 8.0 が選択されていることを確認し、[作成] を選択します。

  6. ソリューション エクスプローラーで、AppHost プロジェクトを右クリックし、[追加] をポイントして、[プロジェクト参照] を選択します。

  7. プロジェクトの一覧で RabbitConsumer が選択されていることを確認し、[OK] を選択します。

    RabbitConsumer プロジェクトを参照する AppHost プロジェクトへの参照を追加する方法を示すスクリーンショット。

  8. ソリューション エクスプローラーで、AppHost を展開し、Program.cs をダブルクリックします。

  9. 次のコードを見つけます。

    builder.AddProject<WebApp>("webapp")
        .WithReference(catalogApi);
    
  10. そのコードの直後に、RabbitConsumer プロジェクトを .NET Aspire オーケストレーションに追加するには、次のコードを追加します。

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

メッセージ コンシューマー プロジェクトを構成する

新しいメッセージ コンシューマー プロジェクトでメッセージを受信するには、AppHost から RabbitMQ バッキング サービスを使用するように構成する必要があります。

  1. Visual Studio のソリューション エクスプローラーRabbitConsumer プロジェクトを右クリックし、[追加] を選んでから、[.NET Aspire パッケージ] を選びます。

  2. 検索テキストボックスの既存のテキストの末尾に「RabbitMQ」と入力します。

  3. Aspire.RabbitMQ.Client パッケージを選択します。

  4. [バージョン] 一覧で最新の 8.0.0 バージョンを選び、[インストール] を選びます。

  5. [変更のプレビュー] ダイアログが表示された場合は、[適用] を選びます。

  6. [ライセンスの同意] ウィンドウで、[同意する] を選択します。

  7. ソリューション エクスプローラーRabbitConsumer プロジェクトを右クリックし、[追加] をポイントして、[プロジェクト参照] を選択します。

  8. プロジェクトの一覧で、eShop.ServiceDefaults が選択されていることを確認し、[OK] を選択します。

    ServiceDefaults プロジェクトを参照する RabbitConsumer プロジェクトへの参照を追加する方法を示すスクリーンショット。

  9. ソリューション エクスプローラーで、RabbitConsumer プロジェクトを展開し、Program.cs をダブルクリックします。

  10. すべての既定のコードを削除し、次の行に置き換えます。

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

    このコードでは、.NET Aspire オーケストレーションを使用して RabbitMQ サービスをコンシューマー プロジェクトに追加していることに注意してください。 そのサービスを使用してメッセージを取得します。

RabbitMQ メッセージを受信する

メッセージを受信するには、メッセージの到着を待機してバックグラウンドで実行されるコンポーネントを作成する必要があります。 このタスクには BackgroundService クラスを使用します。

  1. ソリューション エクスプローラーRabbitConsumer プロジェクトを右クリックし、[追加] をポイントして [クラス] を選択します。

  2. [名前] テキストボックスに「CatalogProcessingJob」と入力し、[追加] を選択します。

  3. CatalogProcessingJob.cs クラスで、すべての既定のコードを削除し、次の行に置き換えます。

     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. ソリューション エクスプローラーRabbitConsumer プロジェクトで、Program.cs をダブルクリックします。

  5. 次のコードを見つけます。

    builder.AddRabbitMQClient("messaging");
    
  6. その行の直後に次のコードを追加します。

    builder.Services.AddHostedService<CatalogProcessingJob>();
    

ソリューションをテストする

RabbitMQ バッキング サービスと、メッセージを送受信するマイクロサービスをテストしてみましょう。

  1. Visual Studio でアプリをデバッグ モードで起動するには、 F5 キーを押すか、デバッグ>[デバッグの開始] を選択します 。

  2. [Docker Desktop の起動] メッセージが表示されたら、[はい] を選択します。 アプリが起動し、ブラウザー タブに .NET Aspire ダッシュボードが表示されます。

  3. .NET Aspire ダッシュボードの [リソース] の一覧で、名前が messaging の新しいコンテナーが一覧に含まれていることに注意してください。 ソースには rabbitmq:3 が含まれます。 このコンテナーは RabbitMQ メッセージ ブローカーを実行します。

    .NET Aspire ダッシュボードに表示されている RabbitMQ コンテナーを示すスクリーンショット。

  4. 左側のナビゲーションで、[コンソール] を選択します。

  5. [リソースの選択] の一覧で、[messaging] を選択します。 このページには、RabbitMQ ブローカーのコンソール ログが表示されます。 最後のいくつかのメッセージは、RabbitMQ が起動を完了し、1 つの接続を受け入れたことを示していることに注意してください。 この接続は、受信側の RabbitConsumer プロジェクトからの接続です。

  6. 左側のナビゲーションで、[リソース] を選択します。

  7. webapp プロジェクトの行の [エンドポイント] 列で、リンクのいずれかを選択します。 Northern Traders のホームページが開き、製品カタログが表示されます。 このページは、RabbitMQ キューにメッセージを送信します。

    .NET Aspire ダッシュボードから WebApp プロジェクト エンドポイントにアクセスする方法を示すスクリーンショット。

  8. .NET Aspire ダッシュボードに切り替えて戻ります。 左側のナビゲーションで、[コンソール] を選択します。

  9. [リソースの選択] の一覧で、[messaging] を選択します。 RabbitQ が 2 つ目の接続を受け入れたことに注意してください。 この接続は Catalog.API プロジェクトからの接続です。

  10. [リソースの選択] の一覧で、consumers を選択します。 このログは RabbitConsumer プロジェクト用です。 最後のエントリには、「Getting all items in the catalog.」というメッセージが表示されます。このメッセージは RabbitMQ から取得され、ログに記録されています。

    RabbitMQ キューから取得され、コンシューマー プロジェクトのコンソール ログに表示されるメッセージを示すスクリーンショット。