fbpx
EDA – Event Driven Architecture: Não confunda eventos com comandos
Publicado em: segunda-feira, 23 de ago de 2021

A diferenciação entre eventos e comandos foi um tema discutido dentro do grupo de arquitetura do Docker Definitivo, e como um tema que gera confusão e ceticismo em alguns aspectos, é hora da gente sair da discussão sobre a parte visível desse iceberg e aprofundarmos na execução e nos cuidados a respeito do tamanho de mensagens e principalmente na diferenciação entre evento e comando.

Quanto vai custar?

No primeiro contato com mensageria você fica maravilhado com esse novo mundo. Sendo bem realista, encontrar em um único conjunto de estratégias: disponibilidade, eficiência, resiliência, confiabilidade e escalabilidade é de tirar o fôlego. É natural que os primeiros contatos produzam grande excitação. Afinal parece que descobrimos uma bala de prata.

Como já estamos vacinados a respeito de balas de prata, é mais que esperado que você se pergunte:

– Ok, incrível! Mas qual é o preço?

Vamos entender quais são os custos envolvidos em torno de mensageria:

  • Ferramental
    • A ferramenta/plataforma
    • Setup
    • Infraestrutura e Hospedagem
  • Implantação
    • O que tecnicamente eu preciso criar na minha aplicação
    • O que tecnicamente eu preciso mudar na minha aplicação.
    • Qual a complexidade?
  • Negócio
    • O que muda no negócio?

Se você está pensando em resolver o envio de email, ou alguma outro caso bem pontual usando mensageria, seu custo total será quase zero. Imperceptível em quase todos os aspectos. Você só verá benefícios sem nenhum onus. Aqui de fato parece uma bala de prata.

Mas quando pensamos em uma Arquitetura Orientada a Eventos, vamos alcançar questões e debates que tornam essa jornada mais complexa. Aqui percebemos custo, mas não é motivo para perder a esperança, se você chegou até aqui, é porque precisa desses benefícios. Não é?!

Como em toda boa arquitetura de referência, fazer concessões e flexibilizar produz o risco de faltar um elemento fundamental, como se produzíssemos um bolo sem fermento. Inevitavelmente concessões e flexibilizações produzem riscos.

O efeitos negativos mais comuns de uma nova arquitetura implementada pela metade são:

  • Aumento da complexidade
  • Aumento do custo
  • Redução na velocidade do time
  • Não obtenção de um, vários, ou até todos os benefícios previstos originalmente

Esses são os primeiros efeitos. Mas temos os efeitos secundários também:

  • Desmotivação do time
  • Desistência / Evasão do corpo técnico
  • Dificuldade de contratação

Em resumo, no pior dos cenários você torna o ambiente mais complexo, mais custoso, menos ágil e ainda não alcança os benefícios pretendidos.

Esse é o típico caso de Microsserviços com bancos de dados compartilhados.

Como mensageria está no coração do Event Driven Architecture, é possível que esse assunto Evento vs Comandos seja negligenciado. Afinal, até então você não diferenciava tipos de mensagem, dessa forma é natural e intuitivo não pensar nas responsabilidades de tipos que sequer nasceram ainda.

E talvez venha à sua cabeça agora: – Precisamos diferenciar?

Você vai ver essa explicação nesse texto ainda.

De onde surgiu essa discussão?

A discussão e as explicações que você vai ver aqui é parte do que discutimos no grupo de arquitetura do Docker Definitivo. Lembrando, são 2 fazes, a primeira só Docker, que dura 40 dias, e a segunda onde abordamos arquitetura… sem prazo de duração.

A galera que entrou nos últimos meses está chegando ao grupo de arquitetura, tendo contato com os conteúdos de arquitetura distribuída e mensageria e a discussão apareceu no chat.

Eu fiz alguns diagramas no celular e compartilhei no grupo, com audios logo após cada um, para explicar a ideia por trás de cada imagem.

Resolvi refazer esses diagramas no Visio, e trazer pra cá, junto com os audios que hospedei na SoundCloud.

Contextualizando

Tudo começa da discussão sobre o Youtube Downloader, projeto de 2017 que é parte do que estudamos no Docker Definitivo.

Nesse projeto o Jessé estava questionando sobre o refresh da UI. Ele perguntou como eu fazia um refresh automático na tela, e eu retruquei explicando não era automático, era apenas o JS fazendo pooling em uma API HTTP que por sua vez obtinha o dado do redis.

Como parte da estratégia de grupo, tudo que é dito é feito de forma a ajudar a esclarecer, então eu continuei falando sobre o porque da decisão e porque não decidi fazer reativo, com SignalR ou Socket.io ou até mesmo Websocket.

Eu disse que não deveria trazer o dado completo pela notificação de evento. Na real pela simplicidade e quantidade de cenários desse projeto, eu até abriria uma exceção. Seria 1 único caso, em todo o projeto, sendo esse um projeto complexo, mas pequeno.

Na prática eu não estava falando do problema do projeto em questão, estava jogando a provocação sobre eventos não serem gordos, provocando a discussão eventos vs comandos, já que eu percebia que estava rolando esse não entendimento, e se ele está nesse módulo, é bem provável que outros também estejam. Essa é a função das turmas no Docker Definitivo.

Eu já havia dito isso algumas vezes no passado mas agora eu precisava falar isso novamente. Em um cenário de arquitetura orientada a eventos precisaria de maior rigor a respeito da responsabilidade de cada tipo de mensagem.

Daí eu comecei a falar da separação entre eventos e comandos.

Parte 1/2

A intenção era demonstrar que buscamos evitar que um novo interessado em um evento, demande modificações no evento. Ou seja, novos campos, e alterações nos dados de um domínio, ou de um microsserviço, não deveria necessariamente produzir modificações nos eventos. Os eventos só deveriam conter ID’s mas a intenção não é fornecer informações completas para que os serviços dependentes realizem todo o processamento.

Parte 2/2

A primeira vez que os alunos escutam isso, eles entram em parafuso. É simples, mas extremamente disruptivo.

– Afinal se esse dado não vem pela mensagem, vem por onde?

– Uma requisição HTTP ou gRPC.

– Mas se tudo que fazemos com mensageria visamos evitar requisições http síncronas, não resilientes, isso parece não fazer o menor sentido.

A questão é que se a produção de um evento se preocupa com seus consumidores, ele tende a mudar a cada novo consumidor. Consumidores que precisam de poucas informações, são penalizados por aqueles que precisam de grandes datasets. Ao mesmo tempo existem consumidores que usam dados do domínio do evento apenas para iniciar a descoberta em outros serviços, provando que a mensagem, mesmo gorda, não é completa.

O emissor do evento não tem controle sobre o momento exato em que o evento será processado, nem tem ciência sobre quem escuta seus eventos. Assim o evento pode ser processado instantaneamente ou após alguns, segundos, horas ou até mesmo dais. Porém entre a produção do evento e o processamento do consumidor pode existir um grande delta e nesse meio tempo o dado original pode ter sido alterado.

Note que ainda não falamos de comandos. Estamos falando apenas de eventos ainda.

O diagrama e audio ilustram isso.

Eventos expressam mudanças de estado significativas, não necessariamente enviando todo o dado.

Como não temos controle da porção de dados necessária para nossos consumidores, produzimos mensagens enxutas, para que cada consumidor use a API adequada para obter dados mais completos.

Nesse processo, a resiliência da requisições para obtenção de dados (HTTP) é assegurada pelo uso de mensageria no processamento do evento.

Ou

O fluxo síncrono não resiliente que estiver contido em um fluxo assíncrono resiliente, tem sua resiliência assegurada pelo fluxo assíncrono.

Comandos

Do outro extremo do prisma, temos os comandos. Eles diferem dos eventos, pois tem foco total em quem consome a mensagem. E é aqui que diferenciamos Eventos de Comandos.

Eventos são enxutos, Comandos são tão gordos quanto o serviço precisa.

Eventos privilegiam chamadas de obtenção de dados adicionais, Comandos privilegiam dados mais completos na mensagem para evitar a complexidade acidental dessas chamadas.

Eventos têm o olhar do Emissor da mensagem, Comandos têm o olhar do consumidor da mensagem.

Evento é uma mensagem de notificação sobre um acontecimento, Comando é uma mensagem de solicitação para execução de uma tarefa.

Conclusão

O acoplamento entre consumidor de um evento e o emissor do evento é inevitável. A questão é se queremos que o produtor também dependa do consumidor.

Optar por eventos enxutos força cada consumidor a usar as API’s adequadas para obter dados na medida certa, em vez de forçar todos os consumidores a receberem todos os dados, que eventualmente ainda podem ficar defasados dado o momento da produção do evento e o momento tardio do processamento do mesmo.

É natural e esperado que existam componentes que recebam eventos e produzam comandos, e componentes que recebam comandos e produzam eventos.

É assim que o fluxo acontece!

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.