연습 - RabbitMQ를 통해 마이크로 서비스 간에 메시지 보내기

완료됨

RabbitMQ는 유연한 메시징 교환 및 큐를 제공하는 신뢰할 수 있는 메시지 브로커입니다. .NET Aspire 프로젝트에서 RabbitMQ를 통해 메시지를 보내고 받으려면 RabbitMQ 컨테이너를 추가한 다음 한 마이크로 서비스에서 메시지를 보내고 다른 마이크로 서비스에서 받는 코드를 만들어야 합니다.

이 연습에서는 Catalog.API 프로젝트의 큐로 메시지를 보냅니다. 큐에서 해당 메시지를 수신하고 표시하기 위해 콘솔 로그로 보내는 새 백그라운드 서비스 프로젝트를 추가합니다.

필수 구성 요소 설치

.NET Aspire의 필수 조건은 다음과 같습니다.

  • .NET 8
  • Visual Studio 2022 미리 보기
  • Docker Desktop 또는 Podman
  • Visual Studio의 .NET Aspire 워크로드

이러한 패키지를 이미 설치한 경우에는 건너뛰고 RabbitMQ 작업을 시작할 수 있습니다.

.NET 8 설치

.NET 8 링크를 따라가서 운영 체제에 맞는 올바른 설치 프로그램을 선택합니다. 예를 들어, Windows 11과 최신 프로세서를 사용하는 경우 Windows용 x64 .NET 8 SDK를 선택합니다.

다운로드가 완료되면 설치 프로그램을 실행하고 지침을 따릅니다. 터미널 창에서 다음 명령을 실행하여 설치가 성공했는지 확인합니다.

dotnet --version

설치한 .NET SDK의 버전 번호가 표시되어야 합니다. 예시:

8.0.300-preview.24203.14

Visual Studio 2022 Preview 설치

Visual Studio 2022 미리 보기 링크를 따라가서 미리 보기 다운로드를 선택합니다. 다운로드가 완료되면 설치 프로그램을 실행하고 지침을 따릅니다.

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 > Api를 확장한 다음 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. 템플릿 검색 텍스트 상자에 콘솔을 입력합니다.

  3. C# 콘솔 앱 템플릿을 선택한 후 다음을 선택합니다.

  4. 프로젝트 이름 텍스트 상자에 RabbitConsumer를 입력하고 다음을 선택합니다.

  5. 프레임워크 목록에서 .NET 8.0이 선택되었는지 확인한 다음 만들기를 선택합니다.

  6. 솔루션 탐색기에서 AppHost 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 가리킨 다음 프로젝트 참조를 선택합니다.

  7. 프로젝트 목록에서 RabbitConsumer가 선택되었는지 확인한 다음 확인을 선택합니다.

    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가 선택되어 있는지 확인한 다음 확인을 선택합니다.

    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. 리소스 선택 목록에서 메시지를 선택합니다. 이 페이지에는 RabbitMQ 브로커에 대한 콘솔 로그가 표시됩니다. 마지막 몇 개의 메시지는 RabbitMQ가 시작을 완료하고 하나의 연결을 수락했음을 나타냅니다. 이 연결은 수신하는 RabbitConsumer 프로젝트에서 이루어집니다.

  6. 왼쪽 탐색 메뉴에서 리소스를 선택합니다.

  7. webapp 프로젝트 줄의 Endpoints 열에서 링크 중 하나를 선택합니다. Northern Traders 홈페이지가 열리고 제품 카탈로그가 표시됩니다. 이 페이지는 RabbitMQ 큐에 메시지를 보냅니다.

    .NET Aspire 대시보드에서 WebApp 프로젝트 엔드포인트에 액세스하는 방법을 보여 주는 스크린샷.

  8. .NET Aspire 대시보드로 다시 전환합니다. 왼쪽 탐색 메뉴에서 콘솔을 선택합니다.

  9. 리소스 선택 목록에서 메시지를 선택합니다. RabbitQ가 두 번째 연결을 수락했습니다. 이 연결은 Catalog.API 프로젝트에서 이루어집니다.

  10. 리소스 선택 목록에서 소비자를 선택합니다. 이 로그는 RabbitConsumer 프로젝트에 대한 것입니다. 마지막 항목에는 "카탈로그의 모든 항목 가져오기"라는 메시지가 표시됩니다. 이 메시지는 RabbitMQ에서 검색되어 기록되었습니다.

    RabbitMQ 큐에서 검색되어 소비자 프로젝트의 콘솔 로그에 표시되는 메시지를 보여 주는 스크린샷.