Упражнение. Отправка сообщений между микрослужбами через RabbitMQ
RabbitMQ — это надежный брокер сообщений, предоставляющий гибкие обмены сообщениями и очереди. Чтобы отправлять и получать сообщения через RabbitMQ в проекте .NET Aspire, необходимо добавить контейнер RabbitMQ, а затем создать код, который отправляет сообщения из одной микрослужбы и получает его в другом.
В этом упражнении вы отправите сообщения в очередь из проекта Catalog.API. Вы добавите новый проект фоновой службы, который получает эти сообщения из очереди и отправляет их в журнал консоли для отображения.
Установка необходимых компонентов
Предварительные требования для .NET Aspire:
- .NET 8
- Visual Studio 2022 Preview
- Docker Desktop или Podman
- Рабочая нагрузка .NET Aspire в Visual Studio
Если вы уже установили эти пакеты, вы можете пропустить работу с RabbitMQ.
Установка .NET 8
Следуйте этой ссылке .NET 8 и выберите правильный установщик операционной системы. Например, если вы используете Windows 11 и современный процессор, выберите пакет SDK x64 .NET 8 для Windows.
После завершения скачивания запустите установщик и следуйте инструкциям. В окне терминала выполните следующую команду, чтобы убедиться, что установка выполнена успешно:
dotnet --version
Вы увидите номер версии установленного пакета SDK для .NET. Например:
8.0.300-preview.24203.14
Установка Предварительной версии Visual Studio 2022
Перейдите по этой ссылке предварительной версии Visual Studio 2022 и выберите "Скачать предварительную версию". После завершения скачивания запустите установщик и следуйте инструкциям.
Установка Docker Desktop
Следуйте этой ссылке Docker Desktop и выберите правильный установщик операционной системы. После завершения скачивания запустите установщик и следуйте инструкциям. Для обеспечения оптимальной производительности и совместимости используйте серверную часть WSL 2.
Откройте классическое приложение Docker и примите соглашение об обслуживании.
Установка рабочей нагрузки .NET Aspire в Visual Studio
Установите рабочую нагрузку .NET Aspire с помощью .NET CLI:
Откройте окно терминала.
Обновите рабочие нагрузки .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): .
Установите рабочую нагрузку .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.
Убедитесь, что рабочая нагрузка .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
для получения примера приложения, которое еще не использует брокер сообщений:
В командной строке перейдите в папку, в которой можно работать с кодом.
Выполните следующую команду, чтобы клонировать пример приложения:
git clone -b aspire-rabbitmq https://github.com/MicrosoftDocs/mslearn-aspire-starter
Создание контейнера RabbitMQ
Начнем с добавления RabbitMQ в проект узла приложения. При запуске решения .NET Aspire добавляет контейнер RabbitMQ в приложение и передает ссылки на проекты, которые используют его:
Запустите Visual Studio и выберите "Открыть проект или решение".
Перейдите в папку, в которой вы клонировали проект.
Дважды щелкните папку "Пуск ", выберите решение eShop.rabbitmq.sln и нажмите кнопку "Открыть".
В Обозреватель решений щелкните правой кнопкой мыши проект eShop.AppHost, выберите "Добавить" и выберите пакет .NET Aspire.
В текстовом поле поиска в конце существующего текста введите RabbitMQ.
Выберите пакет Aspire.Hosting.RabbitMQ .
В списке версий выберите последнюю версию 8.0.0 и нажмите кнопку "Установить".
Если появится диалоговое окно "Предварительные изменения" , нажмите кнопку "Применить".
В диалоговом окне "Принятие лицензии" нажмите кнопку "Принять".
В Обозреватель решений разверните eShop.AppHost и дважды щелкните Program.cs.
Найдите следующую строку кода:
var builder = DistributedApplication.CreateBuilder(args);
Сразу после этого кода добавьте следующий код:
var messaging = builder.AddRabbitMQ("messaging");
Найдите следующий код, который регистрирует проект Catalog.API для оркестрации .NET Aspire:
var catalogApi = builder.AddProject<Catalog_API>("catalog-api") .WithReference(catalogDb);
Чтобы передать службу RabbitMQ в проект Catalog.API , измените этот код, чтобы он соответствовал этому коду:
var catalogApi = builder.AddProject<Catalog_API>("catalog-api") .WithReference(catalogDb) .WithReference(messaging);
Добавление RabbitMQ в проект Catalog.API
Теперь мы можем установить и настроить RabbitMQ в проекте Catalog.API:
В Visual Studio в Обозреватель решений щелкните правой кнопкой мыши проект Catalog.API, выберите "Добавить" и выберите пакет .NET Aspire.
В текстовом поле поиска в конце существующего текста введите RabbitMQ.
Выберите пакет Aspire.RabbitMQ.Client.
В списке версий выберите последнюю версию 8.0.0 и нажмите кнопку "Установить".
Если появится диалоговое окно "Предварительные изменения" , нажмите кнопку "Применить".
В диалоговом окне "Принятие лицензии" нажмите кнопку "Принять".
В Обозреватель решений разверните проект Catalog.API и дважды щелкните Program.cs.
В файле Program.cs найдите следующую строку кода:
var builder = WebApplication.CreateBuilder(args);
Сразу после этой строки добавьте следующий код:
builder.AddRabbitMQClient("messaging");
Отправка сообщения в очередь RabbitMQ
Когда пользователь запрашивает элементы в каталоге, мы хотим отправить сообщение в очередь RabbitMQ, описывающую сведения о запросе. Теперь добавим этот код:
В Обозреватель решений разверните API Catalog.API > и дважды щелкните CatalogApi.cs.
Найдите следующий код, который объявляет
GetAllItems()
метод:public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems( [AsParameters] PaginationRequest paginationRequest, [AsParameters] CatalogServices services) {
Чтобы использовать внедрение зависимостей для получения подключения к RabbitMQ, измените код в соответствии со следующими строками:
public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems( [AsParameters] PaginationRequest paginationRequest, [AsParameters] CatalogServices services, RabbitMQ.Client.IConnection connection) {
Найдите следующую строку кода:
var totalItems = await services.DbContext.CatalogItems .LongCountAsync();
Сразу после этой строки добавьте следующий код:
var channel = connection.CreateModel();
Чтобы создать очередь сообщений, добавьте следующий код:
channel.QueueDeclare(queue: "catalogEvents", durable: false, exclusive: false, autoDelete: false, arguments: null);
Чтобы отправить сообщение, добавьте следующий код:
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, создадим проект:
В Обозреватель решений щелкните правой кнопкой мыши решение, наведите указатель мыши на добавление и выберите новый проект.
В текстовом поле поиска шаблонов введите консоль.
Выберите шаблон консольного приложения C# и нажмите кнопку "Далее".
В текстовом поле "Имя проекта" введите RabbitConsumer и нажмите кнопку "Далее".
В списке Платформы убедитесь, что выбран .NET 8.0 , а затем нажмите кнопку "Создать".
В Обозреватель решений щелкните правой кнопкой мыши проект AppHost, наведите указатель мыши на добавление и выберите "Справочник по проекту".
В списке проектов убедитесь, что выбран RabbitConsumer , а затем нажмите кнопку "ОК".
В Обозреватель решений разверните AppHost и дважды щелкните Program.cs.
Найдите следующий код:
builder.AddProject<WebApp>("webapp") .WithReference(catalogApi);
Сразу после этого кода добавьте проект RabbitConsumer в оркестрацию .NET Aspire, добавьте следующий код:
builder.AddProject<Projects.RabbitConsumer>("consumers") .WithReference(messaging);
Настройка проекта потребителя сообщения
Прежде чем получать сообщения в новом проекте потребителя сообщений, необходимо настроить его для использования службы резервного копирования RabbitMQ из AppHost:
В Visual Studio в Обозреватель решений щелкните правой кнопкой мыши проект RabbitConsumer, выберите "Добавить", а затем выберите пакет .NET Aspire.
В текстовом поле поиска в конце существующего текста введите RabbitMQ.
Выберите пакет Aspire.RabbitMQ.Client.
В списке версий выберите последнюю версию 8.0.0 и нажмите кнопку "Установить".
Если появится диалоговое окно "Предварительные изменения" , нажмите кнопку "Применить".
В диалоговом окне "Принятие лицензии" нажмите кнопку "Принять".
В Обозреватель решений щелкните правой кнопкой мыши проект RabbitConsumer, наведите указатель мыши на добавление и выберите "Ссылка на проект".
В списке проектов убедитесь, что выбран eShop.ServiceDefaults , а затем нажмите кнопку "ОК".
В Обозреватель решений разверните проект RabbitConsumer и дважды щелкните Program.cs.
Удалите весь код по умолчанию и замените его следующими строками:
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
Используйте класс для этой задачи:
В Обозреватель решений щелкните правой кнопкой мыши проект RabbitConsumer, наведите указатель на добавление и выберите класс.
В текстовом поле "Имя" введите CatalogProcessingJob и нажмите кнопку "Добавить".
В классе 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; } }
В Обозреватель решений в проекте RabbitConsumer дважды щелкните Program.cs.
Найдите следующий код:
builder.AddRabbitMQClient("messaging");
Сразу после этой строки добавьте следующий код:
builder.Services.AddHostedService<CatalogProcessingJob>();
Тестирование решения
Давайте протестируем службу резервной копии RabbitMQ и микрослужбы, которые отправляют и получают сообщения:
Чтобы запустить приложение в режиме отладки, нажмите клавишу F5 или выберите "Начать отладку>".
Если появится сообщение "Пуск Docker Desktop", нажмите кнопку "Да". Приложение запускается и отображает панель мониторинга .NET Aspire на вкладке браузера.
На панели мониторинга .NET Aspire в списке ресурсов обратите внимание, что список содержит новый контейнер с обменом сообщениями с именем. Источник включает rabbitmq:3. Этот контейнер запускает брокер сообщений RabbitMQ.
В области навигации слева выберите консоль.
В списке ресурсов выберите обмен сообщениями. На странице отображаются журналы консоли для брокера RabbitMQ. Обратите внимание, что последние несколько сообщений указывают, что RabbitMQ завершил запуск и принял одно подключение. Это подключение осуществляется из полученного проекта RabbitConsumer .
В области навигации слева выберите "Ресурсы".
В строке проекта веб-приложения в столбце Endpoints выберите одну из ссылок. Откроется домашняя страница Northern Traders и отображается каталог продуктов. Эта страница отправляет сообщение в очередь RabbitMQ.
Вернитесь на панель мониторинга .NET Aspire. В области навигации слева выберите консоль.
В списке ресурсов выберите обмен сообщениями. Обратите внимание, что RabbitQ принял второе подключение. Это подключение осуществляется из проекта Catalog.API .
В списке ресурсов выберите потребителей. Этот журнал предназначен для проекта RabbitConsumer . Последняя запись отображает сообщение "Получение всех элементов в каталоге". Это сообщение было получено из RabbitMQ и зарегистрировано.