RabbitMQ com MassTransit no .NET 6

MassTransit é um framework fantástico para comunicação assíncrona em aplicações distribuídas, tanto que a própria documentação cita:

MassTransit é uma estrutura de aplicação distribuída de código aberto para .NET que facilita a criação de aplicações e serviços que potencializam a comunicação assíncrona, baseada em mensagens e fracamente acoplada para maior disponibilidade, confiabilidade e escalabilidade.

Vantagens do MassTransit

  • Código aberto e gratuito
  • Fácil de configurar e utilizar
  • Contém muitos padrões de mensagem de microservices (Retry, circuit braker)
  • Tratamento de exceções integrado
  • Transação distribuída (Saga, event-drive, roteamento)
  • Agendamento de mensagens
  • Monitoramento

A facilidade e a resiliência que o MassTransit nos oferece é absolutamente tudo o que precisamos saber.

Neste artigo, mas uma vez vamos direto ao ponto: Configurar uma API no .NET 6.0 com o cenário de envio de mensagens (publish) para um Worker Service que recebe (subscribe) e processa essas mensagens utilizando o MassTransit.

Pré-requisitos

API

O primeiro passo é configurar o docker-compose com a imagem do RabbitMQ (que é um dos message broker de código aberto mais populares). Basicamente, ele oferece à suas aplicações uma plataforma comum para enviar e receber mensagens, garantindo que os dados nunca sejam perdidos e recebidos com êxito pelos consumidores, além de oferecer suporte a vários protocolos de mensagens.

version: "3.8"
services:

  rabbitmq:
    image: masstransit/rabbitmq
    ports:
      - 5672:5672
      - 15672:15672

Caso não queira utilizar o Docker, é possível utilizar o RabbitMQ em uma conta gratuita no CloudAMQP.

Em seguida é preciso configurar a classe Program da API:

Neste código temos a extensão AddMassTransit responsável por registrar o service bus do RabbitMQ, que está configurado no appsettings.json:

  "ConnectionStrings": {
    "RabbitMq": "amqp://guest:guest@localhost:5672"
  }

Em seguida, precisamos configurar o envio de mensagens na ClientController:

O IPublishEndpoint é a interface genérica responsável pelo envio de mensagens. Independente do provedor escolhido (In Memory, RabbitMQ, Azure Service Bus, etc).

Worker Service

O Worker Service trabalha como uma aplicação executada em segundo plano, responsável apenas por consumir e processar mensagens. Esse tipo de aplicação é uma ótima escolha em ambientes distribuídos / microservices por ser extremamente leve e carregando apenas o necessário, facilitando na escala.

O próximo passo é configurar a classe Program do Worker Service:

A classe Bus (Bus.Factory) é responsável por configurar o consumo das mensagens do RabbitMQ, onde é necessário configurar o ReceiveEndpoint com o nome da queue (que pode ser qualquer nome, já que o envio e recebimento das mensagens pelo MassTransit é definido pelo nome do tipo de objeto, incluindo o namespace).

Outra configuração importante é o UseMessageRetry responsável pela resiliência nas tentativas em caso de erro. Neste exemplo foi configurado em 3 tentativas no intervalo de 100 milissegundos.

No código abaixo temos a definição do Consumer, chamado de WorkerClient:

Tanto na controller como no worker é utilizado o mesmo objeto (ClientModel) para o envio e recebimento.

Solução Completa

No final, a solução fica com essa estrutura:

  • Sample.Masstransit.WebAPI: API responsável pelo envio de mensagens.
  • Sample.Masstransit.Worker: Worker Service responsável pelo recebimento das mensagens.
  • Sample.Masstransit.WebApi.Core: Abstrações genéricas utilizado pela API e Worker

Para realizar os testes é preciso configurar a solução com a inicialização simultânea do projeto WebApi e Worker e executar o comando docker-compose na pasta raiz do projeto:

docker-compose up

Testando a aplicação é possível ver o envio e recebimento de mensagens orquestrado MassTransit:

Finalizando, o MassTransit é sem dúvida a melhor abstração na utilização de message brokers, podendo ser utilizado em vários cenários, como por exemplo, em migrações de aplicações legadas para novas arquiteturas, onde é necessário manter várias bases de dados atualizadas, sendo necessário o envio de mensagens para topics em um bus para a sincronização das bases.

Os detalhes completo sobre a implementação do MassTransit no .NET 6.0 você encontra no meu GitHub:
https://github.com/hgmauri/sample-masstransit

Deixe uma resposta