fbpx
Publicado em: sábado, 21 de out de 2023
RabbitMQ e .NET – Usar ou não usar bibliotecas?

Nesse post detalho meus argumentos para que você não use nenhuma abstração e use o cliente nativo do RabbitMQ feito para .NET.

Contexto

RabbitMQ é o Message Broker mais usado do mercado, uma solução open source e amplamente difundida.

O projeto adota AMQP 0.9.X enquanto Azure Service Bus, Apache QPID, e diversos outros concorrentes utilizam AMQP 1, por exemplo.

RabbitMQ até a versão 3 implementava AMQP 1.0 via plugins, mas agora na versão 4, já traz o AMQP 1.0 para seu core, mantendo o respeito ao AMQP 0.9.x.

AMQP 0-9-X vs AMQP 1

Esse tópico daria um post inteiro para detalhar a história por trás dessa confusão.

O que você precisa saber é que o RabbitMQ já vinha com a implementação do AMQP 0-9-X antes do nascimento do AMQP 1.

A proposta final da primeira versão do AMQP não agradou à equipe do RabbitMQ, que optou por continuar usando o AMQP 0-9-X no core do projeto, suportando opcionalmente o AMQP 1.x via plugin, agora trazendo para o core.

A principal diferença para o contexto desse post aqui está na presença de Exchanges e Filas no AMQP 0-9-X e a ausência de definições sobre objetos internos do broker no AMQP 1.X.

AMQP 0.9.xAMQP 1.0
Define Protocolo de Comunicação com o BrokerDefine Protocolo de Comunicação com o Broker
Define objetos internos como exchanges, filas e binds

Um mar de possibilidades

Existem muitas configurações que não são feitas em um arquivo de configuração. Muitas dessas configurações estão em cada fila, cada exchange, cada mensagem. Essas configurações precisam de match entre si para alcançarmos nossos objetivos.

Nos raros casos de incompatibilidade até teremos exceptions, mas em uma parcela significativa, geramos configurações compatíveis, funcionais, válidas, mas que não atendem ao nosso desejo.

É aqui que mora a parte complicada da coisa.

A solução é altamente configurável, portanto você pode:

  • Criar filas persistidas em disco.
  • Filas em memória.
  • Filas dinâmicas que duram o tempo de 1 operação.
  • Filas que persistem quando o servidor reinicia.
  • Ou filas que desaparecem quando o servido reinicia.

Ainda pode, no nível da mensagem decidir se:

  • A mensagem é persistida em disco, como garantia.
  • A mensagem não é persistida em disco, sem garantia.
  • A mensagem precisa alcançar uma fila.
  • A mensagem não precisa alcançar uma fila.

No consumo você ainda pode:

  • Decidir que o Message Broker entenderá que a mensagem já foi processada, assim que o processo pegar a mensagem para trabalhar.
  • Decidir que o Message Broker entenderá que a mensagem já foi processada, somente após finalizar o processamento da mensagem.

Não estou preocupado em montar uma lista completa nesse post porque não é o objetivo, mas isso é o que me vem à cabeça no instante que escrevo.

O ponto é que há muitas coisas para nos preocuparmos e muitas decisões para tomarmos ao trabalhar com RabbitMQ.

Sobre o consumo de mensagens

Aqui vai uma lista com os principais tópicos que você deve se preocupar ao consumir mensagens do RabbitMQ.

  1. Ciclo de vida da Connection
  2. Ciclo de vida do Model/Channel
  3. QoS/Prefetch
  4. Desserialização
    • Como lidar com exceção na desserialização (reject com requeue false)
  5. Consumo
    • Usar consumidor (remover, caso haja, uso de BasicGet)
  6. Ack
    • Ack Manual ou automático.
    • Chamada ao Ack
    • Chamada ao Reject
    • Controle de Exceptions (reject agora com requeue true, rever fluxo de deadletter)
  7. Exchange (validação sobre como a mensagem chega nas suas filas)
    • Tipo (Fanout, Topic, Direct, Headers …)
    • Alternate Exchange
  8. Queue
    • Configurações básicas (durável, autodelete etc etc)
    • DeadLetter (exchange e routing key)
  9. Dispatch
    • RootScope
    • Scopeless
    • ChildScope

Considere essa lista como um checklist, onde você precisa ter as respostas para todas essas questões.

Por que não recomendo o uso de bibliotecas?

Toda a lista do tópico anterior demanda decisões, validações, portanto ao trabalhar com RabbitMQ você precisa tomar uma série de decisões, para cada contexto, tanto para configuração, consumo e publicação então:

Se você não está tomando essas decisões, alguém tomou-as por você!

Luiz Carlos Faria

Essa é uma frase que serve para o consumo de mensagens do RabbitMQ, mas também serve para a vida.


Embora você possa delegar essas questões para uma biblioteca, na maior parte do tempo não há nem certo, nem errado.

Vai depender do que você quer, e do comportamento que você espera.

Assim, se você não sabe o que a biblioteca faz, qual estratégia ela adota, você está sendo negligente.

Terceirizar a complexidade para uma biblioteca,
NÃO ter dá carta-branca
para “não saber”
para “não se importar”.

Infelizmente, na prática, presume-se que a abstração tomou decisões corretas, mas, na verdade, não.

Como para a maioria desses assuntos não há uma decisão certa, nem errada, quando há negligência o perrengue é certo e o sucesso é uma mera obra do acaso.


A pior forma de fracassar é por pura e inadvertida:

negligência.


Não há nada de errado em usar abstrações.
Agora que você tem as perguntas certas, é hora de buscar respostas (com ou sem libraries)!
Parte importante do seu trabalho é assegurar que estamos usando cada recurso da forma certa.

0 comentários

Enviar um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

Lives

Fique de olho nas lives

Fique de olho nas lives no meu canal do Youtube, no Canal .NET e nos Grupos do Facebook e Instagram.

Aceleradores

Existem diversas formas de viabilizar o suporte ao teu projeto. Seja com os treinamentos, consultoria, mentorias em grupo.