Typefully

🇧🇷 Padrões de Sistemas Distribuídos: Outbox Pattern

Avatar

Share

 • 

4 years ago

 • 

View on X

🇧🇷 Bom ponto que o @rponte traz aqui. Existem algumas ferramentas possíveis para resolver isso em arquiteturas distribuídas e orientadas à mensagens. Uma delas é um pattern fundamental nesse tipo de ambiente chamado Transactional Outbox. twitter.com/rponte/status/1505745458878103557
O Transactional Outbox Consiste em: 1) Numa mesma transação na BD salvar um registro na tabela correspondente e a mensagem produzida por essa ação numa segunda tabela chamada Outbox; 2) Ter uma thread em background a fazer polling no Outbox pra publicar a mensagem no broker;
Esse pattern traz a garantia de que mensagens - comumente eventos - são produzidas de maneira consistente à alterações de estados em registros.
Problemas? Esse pattern assume uma garantia de entrega de mensagens chamada de at-least-once. Isso quer dizer que a mensagem produzida, vai ser publicada ao menos uma vez no broker e pode - excepcionalmente - ser publicada mais de uma vez.
Como a mensagem pode ser publicada mais de uma vez? Imagine que o Message Relay leu a mensagem, enviou para o broker mas antes de salvar na Outbox que a mensagem foi publicada, a aplicação falha. No restart da app, o Relay vai ver a mensagem ainda no outbox e republicá-la.
Como prevenir isso? Ao trabalhar com at-least-once, é importante que os seus consumidores de mensagens sem idempotentes: isso é, caso eles recebam a mesma mensagem mais de uma vez, o estado não pode se alterar / o comportamento tem de ser o mesmo.
Por exemplo: uma mensagem de UsuarioCriado é produzida junto com um novo usuário criado, e existe um consumidor pra essa mensagem que dispara um e-mail de boas vindas. Um consumidor idempotente poderia receber a mesma mensagem n vezes, mas não dispararia e-mail mais de uma vez.
Building blocks do outbox: Na infraestrutura: uma BD com suporte à transações e um message broker. Nas aplicações produtoras: background thread pra fazer polling, publicar a mensagem e gerenciar o outbox. Nas aplicações consumidoras: consumidores idempotentes.
Existem várias libs hoje que já facilitam esse trabalho de implementação do outbox nas mais diversas linguagens. No C#, por exemplo, temos o CAP - cap.dotnetcore.xyz/ - que é um framework com outbox/inbox já implementado pra produzir/consumir mensagens.
Sistemas distribuídos são lindos - eu acho pelo menos - mas cheios de pequenos detalhes. Não basta adicionar um message broker e achar que todos seus problemas estão resolvidos. Ao mesmo tempo, um mundo incrível de se estudar!
Bom conteúdo sobre Outbox nos links abaixo: @crichardson microservices.io/patterns/data/transactional-outbox.html @codeopinion Reliably Save State & Publish Events (Outbox Pattern) - YouTube youtube.com/watch?v=u8fOnxAxKHk&ab_channel=CodeOpinion
Avatar

Mateus Viegas

@mateuscviegas

Domain-driven systems thinker, husband, photographer and amateur runner. pt/en