Mensageria com RabbitMQ e ASP.NET Core – Parte #1

Neste artigo vou falar sobre como integrar sua aplicação ASP.NET Core com o RabbitMQ.

Antes de falar como isso será feito, vou falar brevemente sobre conceitos de mensageria, como a fila e a mensagem, e também sobre o próprio RabbitMQ e conceitos específicos a ele.

O exemplo apresentado será de uma API que receberá dados de entrada sobre uma mensagem instantänea de usuário em uma rede social, e a aplicação então publicará esses dados em uma mensagem para uma fila do RabbitMQ.

Código fonte aqui.


Quer ser notificado sobre os próximos artigos, lives semanais, eventos e treinamentos? Entre no canal LuisDev no Telegram!


Introdução

Alguns conceitos a respeito de mensageira são essenciais para que se possa entender o RabbitMQ, e como ocorre o processamento de mensagens.

  • Mensagem: são um bloco de dados, em formato binário. Uma mensagem pode conter dados em diferentes formatos, como texto, JSON, XML, etc.
  • Fila: armazena diversas mensagens enquanto o cliente ou consumidor delas não as retira dela. Em uma fila, uma mensagem não pode ser processada mais de uma vez. Imagine como se fosse uma carta normal, indo para sua caixa de correio.
  • Tópico: semelhante a uma fila, porém permite envio de cópias de mensagens a diferentes clientes (ou assinantes). 

O fluxo, de maneira resumida, é o seguinte:

  • Uma mensagem é publicada em uma fila, sendo armazenada ali até que algum cliente a consuma;
  • Um cliente da fila solicita a próxima mensagem dela, a retirando da fila e processando;
  • Em caso de erro no processamento (e dependendo da configuração sobre reconhecimento, ou acknowledgement), a mensagem deve ser devolvida.

RabbitMQ

O RabbitMQ é o servidor de mensageria open-source mais famoso atualmente, sendo utilizado por empresas de todos os tamanhos.

Ele é desenvolvido em Erlang, e utiliza o protocolo AMQP para suporte a mensagens. Assim como o conceito de mensageria no geral, ele ajuda aplicações escalarem seu processamento através do processamento assíncrono das mensagens que são publicadas nele. Dentre as suas características e funcionalidades, encontra-se:

  • Tópicos;
  • Dead-letter queues
  • Agendamento de entregas
  • Envio em batch (ou lotes)
  • Transações
  • Deduplicação

Clique aqui para mais informações sobre o RabbitMQ.


Filas no RabbitMQ

Mesmo não sendo o objetivo desse artigo tratar o RabbitMQ em profundidade, é essencial entender alguns conceitos relacionados a fila no RabbitMQ.

A fila no RabbitMQ tem algumas características, que são importantes de se entender:

  • Durável: se sim, metadados dela são armazenados no disco e poderão ser recuperados após o reinício do nó do RabbitMQ. Além disso, em caso de mensagens persistentes, estas são restauradas após o reinício do nó junto a fila durável. Em caso de uma mensagem persistente em uma fila não-durável, ela ainda será perdida após reiniciar o RabbitMQ.
  • Auto-Delete: se sim, a fila vai ser apagada caso, após um consumer ter se conectado, todos se desconectaram e ela ficar sem conexões ativas.
  • Exclusiva se sim, apenas uma conexão será permitida a ela, e após esta encerrar, a fila é apagada.

Outros conceitos importantes de se entender são os de Exchange e Routing Key.

  • Exchange: são agentes responsáveis por rotear as mensagens para filas, utilizando atributos de cabeçalho, routing keys, ou bindings.
  • Routing Key: funciona como um relacionamento entre um Exchange e uma fila, descrevendo para qual fila a mensagem deve ser direcionada.

Instalando o RabbitMQ

Existem diversas maneiras de instalar o RabbitMQ, mas a que eu gostei muito, para Windows, foi usando o Chocolatey.

De qualquer forma, deixo o link para que você escolha a maneira que se encaixar melhor em sua situação.

https://www.rabbitmq.com/install-windows.html

Após iniciar o serviço, acesse o portal de gerencialmente pelo link http://localhost:15672/. A tela de login aparecerá.

Tela de login do RabbitMQ

O usuário e senha padrões são guest. Autenticando, você terá acesso à tela de Overview da ferramenta.

Página de Overview do RabbitMQ

A fila será criada via código, mas se você quiser, é possível fazer isso indo na aba “Queues”, clicando em “Add a New Queue” , preencher os dados, e finalizar clicando em “Add queue.


Integrando com ASP NET Core

Assim como com o Azure Service Bus, integrar uma aplicação ASPNET Core com o RabbitMQ é simples. Será mostrado o passo-a-passo a seguir para fazer, considerando um exemplo de aplicação de mensagem instantânea.

Instalando os pacotes necessários

O pacote a ser utilizado é o RabbitMQ.Client. Assim como outros pacotes, é possível instalá-lo de duas maneiras: dotnet CLI e Gerenciador de Pacotes NuGet.

Abaixo está o código para instalar o pacote via dotnet CLI.

Instalando o pacote RabbitMQ.Client via .NET CLI

Se preferir utilizar o Gerenciador de Pacotes NuGet, basta buscar pelo pacote de mesmo nome lá, e instalá-lo.

Instalando o pacote RabbitMQ via gerenciador de pacotes NuGet

Vamos ao código para publicar uma mensagem!

Publicando uma mensagem

Antes de mostrar o código de publicar uma mensagem no RabbitMQ, mostro logo abaixo o modelo do objeto que será enviado junto a ela.

Modelo de entrada para a API, bem como de mensagem ao RabbitMQ

Basicamente, ele representa uma mensagem de um usuário FromId, para um usuário ToId, com o conteúdo Content.

É criado um controller nomeado MessagesController, que tem um endpoint de método HTTP POST. Ele vai receber a mensagem, converter ela para string, para em seguida tornar ela um array de bytes. Com isso, será possível publicar a mensagem.

A classe ConnectionFactory é utilizada para configurar a conexão com o RabbitMQ, permitindo criar uma instância de IConnection, que estabelece a conexão TCP com o broker do RabbitMQ. Finalmente, com essa conexão, é criada um canal (ou channel), que nada mais é do que uma conexão virtual com o RabbitMQ, utilizando o protocolo AMQP. Múltiplos canais compartilham uma conexão TCP única.

Código do Controller, que realiza a publicação de uma mensagem no RabbitMQ

O método QueueDeclare cria uma fila, e é indepotente. Isto é, ele só vai criar a fila em caso de sua inexistência, não realizando nada caso já exista.

Já o método BasicPublish, realiza a publicação da mensagem (que está em formato Array de Bytes), passando o exchange padrão, e como Routing Key o nome da fila.

Testando

Usando o Swagger, que já vem configurado no .NET 5, enviamos a requisição com um objeto JSON no corpo dela, recebendo na resposta um status 202 Accepted.

Realizando a requisição via Swagger

Em seguida, podemos consultar a mensagem publicada indo na aba Queues, selecionando a fila messages, acessando o item Get messages, e finalmente apertando em Get Message(s)

Consumindo uma mensagem pelo gerenciador do RabbitMQ

Na Parte 2 veremos como consumir essa mensagem e obter o objeto enviado!


Inscreva-se na lista de espera do Método .NET Direto ao Ponto, um treinamento completo sobre C#, APIs com ASP.NET Core e Microsserviços:  Inscreva-se aqui.

São quase 200 vídeo-aulas sobre temas como C#, ASP NET Core 5, EF Core, CQRS, Clean Architecture, Autenticação e autorização com JWT, Testes Unitários, além de mini-cursos em Microsserviços, Performance em .NET, ASP NET Core e Azure, Docker, Carreira Internacional em .NET, e mais.


Conclusão

Nesse artigo foram apresentados os principais conceitos de mensageria, bem como a ferramenta RabbitMQ. Também foram apresentados conceitos específicos dela, como Exchange e Routing Key.

Finalmente, foi feita a implementação de um endpoint em um projeto ASP NET Core onde é feita a configuração e conexão com o RabbitMQ, e o envio de uma mensagem para uma fila dele.

Se gostou, compartilhe!

Até o próximo artigo!