fbpx
EasyNetQ em perspectiva
Publicado em: segunda-feira, 24 de maio de 2021
Categorias: RabbitMQ de A a Z

Abstrações são desenhadas para resolver problemas e abstrair um ou mais aspectos de uma implementação. Uma abstração pode entregar redução de complexidade, maior coesão, configuração facilitada, adaptação e até mesmo suprimir aquilo que não nos é relevante quando um novo padrão emerge do seu próprio uso.

Hoje o debate é sobre o EasyNetQ, uma abstração de muito sucesso aqui na comunidade .NET. Conta hoje com 8.6 milhões de downloads no nuget.org (link), enquanto o provider nativo RabbitMQ.Client possui seus 53 milhões (link). É um número surpreendente, visto que a abstração depende do provider nativo.

Embora eu prefira tratar desse assunto “dentro de casa” com alunos, evitando assim a exposição da crítica, e principalmente a taxação de estar “cagando regra” por aí. Acho que é importante trazer o tema para a pauta aqui no gaGO.io.

Entenda, “dentro de casa”, a discussão fica mais fácil, eu consigo demonstrar claramente questões internas e cases de insucesso e misconception causados pela falta de experiência com o RabbitMQ.Client e com RabbitMQ em si, que passam a ganhar proporções maiores quando o primeiro e único contato com o RabbitMQ acontece via uma abstração.

Não há nada de errado com o uso de abstrações. Mas não podemos desconsiderar que uma abstração é uma releitura da tecnologia.

Como qualquer releitura possui o viés que o autor resolveu dar ao projeto.

As abstrações são nocivas ao aprendizado

Abstrações são boas, desde que você saiba o que está fazendo. Desde que você concorde com a abstração. E é aqui que os novatos pecam. Ter o primeiro contato com uma tecnologia via uma abstração, em um momento em que ainda não se tem muita certeza e confiança sobre a tecnologia, sobre como as coisas funcionam, tem enorme potencial de gerar entendimentos errados e confusão.

O que parecia simplificar, sacaneia todo o entendimento de como as coisas de fato funcionam. São expectativas frustradas, seja porque a abstração faz algo a mais, algo a menos ou simplesmente diferente.

Até suas pesquisas no google são ineficientes se você aprende termos que não são os corretos. Inclusive acredito que possa escrever só sobre isso. Tem muita coisa a respeito de estratégia de estudo que faz sentido trazer sobre isso.

Mas como essa discussão apareceu? Deixa eu pontua 2 eventos que me trouxeram até aqui para essa discussão.

Exemplos

Não faz nem 1 mês que um aluno recém chegado à masterclass de RabbitMQ comentou:

Esse questionamento parece normal, no entanto o problema é que no RabbitMQ não existe SubscriptionId. Para consumir uma fila, basta um model conectado no RabbitMQ e o nome da fila.

Já nessa semana, em um grupo público do telegram:

O problema é que replica para o RabbitMQ, não é um assunto relacionado ao consumo de mensagens, mas relacionando alta disponibilidade e filas que estão em diversos nós de um cluster.

O problema é deles!?

Você pode dizer: – Ah, mas o problema é deles!

Em algum nível eu até concordo, eles escolheram ir por esse caminho como primeiro contato.

Mas entendo que o óbvio também precisa ser dito e acredito que seja preciso criar esse alerta, chamar a atenção para esse padrão.

O fato é que uma pesquisa por SubscriptionId, no contexto do RabbitMQ, só trará assuntos relacionados ao EasyNetQ. E nada sobre o RabbitMQ. Porque não há esse conceito no RabbitMQ.

O problema reside quando a abstração está te empurrando em uma direção, que parece mais simples, mas carrega consigo decisões que não necessariamente você queria ou está pronto para tomar nesse primeiro contato. Nesse momento sequer dá para saber se a decisão é boa ou ruim.

Abstração: Mocinho ou Vilão

Não há uma resposta categórica: Depende do objetivo.

Se você quer aprender ASP.NET ignorando SQL, uma abstração como um ORM é bem proveitosa, pois abstrai um conhecimento periférico adicional que embora seja relevante, nas faz parte do objeto de estudo.

No entanto, se você quer ser um bom profissional, saber SQL é fundamental, e não necessariamente você deve usar ADO puro, mas eu sinceramente acredito que se seu foco for compreender melhor acesso a dados, sim faz sentido usar pelo menos algumas vezes ADO puro.

O que faz uma abstração ser boa ou ruim para o aprendizado, depende do que está sendo abstraído e do objeto de estudo.

Um ORM é nocivo para quem quer entender como usar um banco de dados, da mesma forma que o EasyNetQ é nocivo para quem quer aprender RabbitMQ.

Sobre o EasyNetQ

A respeito do RabbitMQ, qualquer abstração que suprima Exchange, Routing Key e Headers, na minha opinião, é nociva tanto ao aprendizado quanto ao uso. O EasyNetQ em diversos momentos privilegia formas de uso em que não sabemos quem são as exchanges, as routing keys e os cabeçalhos das mensagens, mesmo que ofereça mecanismos para interagir com esses objetos.

Esses mecanismos estão escondidos, tanto nas interfaces, como na documentação.

Isso acontece em algumas implementações, como a de Pub/Sub, mas não acontece, por exemplo na implementação do IAdvancedBus. O que eu tenho a ressaltar aqui é a força que a documentação faz para te jogar na direção errada. Ela privilegia o envio de objetos para o broker, ignorando os principais aspectos que citei acima.

Esses 2 exemplos que marquei em vermelho, demonstram o viés usado pela implementação mais privilegiada na solução.

A publicação da mensagem deveria pelo menos ter mais 2 parâmetros: routing key e exchange, duas strings.

A forma como sua interface foi proposta faz com que ele adote convenções quando não especificamos tais detalhes. Essa é uma abordagem interessante para quem está habituado com o RabbitMQ e sabe exatamente o que precisa, mas uma estratégia ruim e nociva para o aprendizado e introdução de novos usuários. Se a interface padrão suprime dados como Routing Key, Headers e Exchange, a abstração precisa inferir e arbitrar como produzir esses dados e é aí que mora o problema. Essa abordagem padrão proposta em toda documentação do EasyNetQ, realiza a criação de filas e exchanges com base nos tipos da classe usadas como mensagem. Ele abstrai filas e exchanges.

O SubscriptionId, por exemplo, é algo que não existe no RabbitMQ, é um conceito exclusivo do EasyNetQ.

É preciso ter atenção dobrada com a terminologia, pois a documentação te empurra na direção de uma simplificação que não se traduz em simplicidade. Na meu entendimento se reflete em acoplamento e perda de funcionalidades básicas do RabbitMQ.

O que você perde ao não lidar com Exchanges?

A exchange desacopla publishers (quem publica mensagem) das filas. Ela é um mecanismo de roteamento. Cada exchange possui um tipo, e de acordo com o tipo, regras diferentes são usadas para rotear uma mensagem para uma ou mais filas.

Ignorar as exchanges

Ignorando a exchange, você não está deixando de usá-las, mas adotando uma forma que ignora suas capacidades, e a forma como é feito pelo Pub/Sub do EasyNetQ pode forçar você a:

  • Ter de construir novas classes, com o único intuito de enviar o mesmo dado para diversos consumidores.
  • Não conseguir realizar a distribuição de mensagens na cardinalidade de 1 x N enviando apenas 1 mensagem.

O que você perde ao não lidar com Filas?

No que diz respeito às filas, o EasyNetQ utiliza o Fully Qualified Name do tipo de mensagem como nome de fila, somado opcionalmente por uma string informada pelo usuário chamada SubscriptionId. Olha a maldita aqui.

A SubscriptionId serve para diferenciar consumer groups da mesma mensagem, pois ela é usada para diferenciar filas que recebem um mesmo tipo de mensagem.

Embora me cause estranheza, nessa parte não há muitas questões.

O que você ganha com o EasyNetQ?

  • Serialização automática
  • Ack Manual Automático

O que o Pub/Sub faz e como faz?

Na estratégia de Pub/Sub desse projeto, a exchange leva o Fully Qualified Name do tipo da mensagem apenas, enquanto as filas usam a mesma string somada ao SubscriptionId.

A infra de Pub/Sub produz uma exchange por Tipo de mensagem, e uma fila por Tipo de Mensagem + SubscriptionId.

Adicionalmente um bind por fila é produzido com routing key igual a #, de forma a toda mensagem daquele tipo, ser roteada para todas as filas que aceitam mensagens desse mesmo tipo.

Nessa abordagem, a razão entre Exchanges e Filas tende a ser 1 para 1, ou 1 x N onde N é cada SubscriptionId.

Conclusão

Na publicação de mensagens a documentação da abstração de pub/sub te empurra para usar exchanges do tipo topic, muitas vezes suprimindo até a routing key. As buscas por apenas publicar a mensagem, sem discriminador de exchange e routing key, tornam o entendimento do RabbitMQ frágil e passa a ser um esforço mental, lembrar dos conceitos básicos do que é uma exchange e para que serve.

O EasyNetQ usado como a documentação sugere, é um problema e um ofensor.

Você pediu e agora virou curso. Mensageria .NET é minha formação de especialista em RabbitMQ com .NET, onde ensino RabbitMQ do básico, cada fundamento, cada detalhe, ao avançado.

Onde você vai sair do zero absoluto e vai conseguir criar, projetar e corrigir soluções .NET com RabbitMQ.

Além de contar mais 3 outros bonus incríveis para ajudar todos que precisam de um up na carreira.

RabbitMQ Newsletter

Novidades e ofertas de conteúdo exclusivo e único no Brasil.

Hoje com orgulho somos referência quando se fala em RabbitMQ com .NET.

São quase 10 anos usando RabbitMQ em projetos .NET com C#, implantando, convencendo times e mostrando o caminho para aslcançar sos 5 benefícios.

Após centenas de pedidos, criei um curso dedicado aos profissionais .NET. 

Aqui nessa newsletter eu te entrego promoções e links especiais! Cola aqui, tem muita coisa legal!

Luiz Carlos Faria

Meu primeiro contato com RabbitMQ foi em 2013.

Eu estava sozinho na definição de uma arquitetura para a reestruturação de uma integração enquanto meu time estava ocupado com o dia-a-dia.

Naquela época eu precisava de apenas 1 ou 2 recursos que o RabbitMQ entregava.

Nas primeiras semanas e meses em produção pude perceber coisas que não estavam escritas em lugar algum, benefícios e formas de uso das quais poderiam resolver anos de frustração.

Desde então RabbitMQ tem sido meu aliado na restruturação de projetos dos mais variados.

E por mais simples que seja, ainda é possível, 10 anos depois, gerar surpresas com novas abordagens que geram novos benefícios.

7 dias

É tudo que precisa para sair do zero, à produção!

Com conforto, com segurança, e com apoio.

Desde que você já seja um desenvolvedor profissional.

Se você quer entregar mais Disponibilidade, Eficiência, Resiliência, Confiabilidade e/ou Escalabilidade, em projetos .NET, aqui é o seu lugar.

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.