Para começar, vou compartilhar sobre um padrão que eu aprendi a partir de alguns questionamentos próprios sobre como garantir a atomicidade de persistência de dados e envio de mensagens em um message broker. É um cenário muito comum uma arquitetura orientada a serviços/microsserviços!
Nesta primeira parte vou abordar o aspecto teórico, e no próximo artigo vou mostrar como implementá-lo com ASP.NET Core.
Vamos lá?
O problema
Não é querendo ser pessimista, mas eu curto pensar no estilo de “e se este componente da arquitetura falhar?” quando estou implementando uma aplicação. Um dos questionamentos que surgiu durante o desenvolvimento de serviços, e que envolviam publicação de mensagens em uma fila, é: e se por alguma razão a mensagem, após a persistência da entidade/agregado, falhar em ser publicada pela aplicação?
Neste cenário, utilizar uma transação distribuída entre um banco de dados e um message broker não é viável.
Eventos de domínio/integração são essenciais para o bom funcionamento de arquiteturas orientadas a evento. Imagina o cenário:
- Usuário realiza um pedido no e-commerce;
- O microsserviço Order processa a requisição, persistindo ao final o agregado Order em seu banco de dados;
- Após persistir, vai publicar o evento OrderCreated, com os dados do pedido, para que outros microsserviços como Payment ou Warehouse trabalhem em cima dele e possam seguir o fluxo do negócio
- Porém, a publicação da mensagem falha;
- A requisição termina com o agregado Order persistido, mas sem os eventos publicados no message broker. Por conta disso, o fluxo está interrompido já que sem a mensagem os outros microsserviços não vão dar seguimento no processo.
Pensa bem nesse cenário. Como você vai tentar publicar novamente a mensagem? Parece simples, mas exige uma estrutura mínima para ser feito posteriormente. Afinal, o status do pedido já pode estar em WaitingForPayment ou WaitingForShipping. Em teoria, já deu “certo”. Não existe no negócio um status OrderCreatedPublishedToMessageBroker, correto?
Nesse cenário, o padrão Outbox surge como uma boa opção para garantir a consistência de dados.
Padrão Outbox
Também conhecido como Transactional Outbox, ele auxilia nesse cenário através de uso de uma tabela Outbox (pode nomear como quiser, foca no conceito).
Essa tabela teria como objetivo armazenar os dados da mensagem ou evento, e seus dados seriam armazenados ali como uma transação junto com a persistência da entidade/agregado do negócio.
Para fins didáticos, vou utilizar o termo job para representar um serviço que será executado em segundo plano, de forma recorrente. Em ASP.NET Core poderia ser um Hosted Service, por exemplo.
Após isso, um serviço/worker/job poderia então processar essas mensagens que estão na tabela Outbox, enviá-las ao message broker, e então atualizar seu status para confirmar o envio. Isso geralmente envolve o uso de uma coluna/campo PublishedAt, que seria nulo enquanto a mensagem não fosse processada por esse job.
Para facilitar o entendimento, criei um diagrama simples representando o padrão e situação descritos.
Como implementar
Um passo a passo para implementar esse padrão é:
- Criar uma tabela Outbox, com os dados de mensagem/eventos;
- Persistir mensagens/eventos de integração na tabela Outbox, e entidades/agregado de maneira transacional;
- Implementar um job recorrente, que vai buscar os eventos que não foram publicados e publicá-los no message broker, e finalmente marcá-los como publicados na tabela Outbox.
No próximo artigo vou mostrar um exemplo de implementação desse padrão utilizando ASP.NET Core e RabbitMQ.
Quer alavancar sua carreira como Desenvolvedor(a) .NET?
Opa, aqui é o Luis Felipe (LuisDev), criador do blog LuisDev.
Além de Desenvolvedor .NET Sênior, eu sou instrutor de mais de 700 alunos e também tenho dezenas de mentorados.
Conheça o com mais de 800 video-aulas sobre C# e desenvolvimento de APIs com ASP NET Core, Microsserviços com ASP NET Core, Arquitetura de Software, Computação em Nuvem, SQL, HTML, CSS e JavaScript, JavaScript Intermediário, TypeScript, Desenvolvimento Front-End com Angular, e Desenvolvimento Front-end com React. Diversos mini-cursos disponíveis aos alunos e atualizações gratuitas.
Suporte dedicado, e comunidade de centenas de alunos.
Completo e online, destinado a profissionais que querem dar seu próximo passo em sua carreira como desenvolvedores .NET.
Clique aqui para ter mais informações e garantir sua vaga
Para concluir, te desafio a:
- Minimizar este artigo;
- Abrir o bloco de notas ou mesmo pegar um caderno/folha;
- Escrever o que entendeu do padrão Outbox;
- Enviar um áudio para algum amigo da área explicando para ele.
Garanto que vai ajudar bastante na retenção do conhecimento obtido aqui.
Até o próximo artigo!