O blog da AWS

Implementando o padrão de caixa de saída transacional com o Amazon EventBridge Pipes

Por Sayan Moitra, arquiteto associado de soluções, Sangram Sonawane, arquiteto de soluções sênior e adaptado para Português por Daniel ABIB, arquiteto sênior de soluções.

A arquitetura de microsserviços é um estilo arquitetônico que define um aplicativo como uma coleção de serviços fracamente acoplados e que podem ser implantados de forma independente. Os serviços devem se comunicar entre si para trocar mensagens e realizar operações comerciais. Garantir a confiabilidade das mensagens e, ao mesmo tempo, manter um acoplamento frouxo entre os serviços é crucial para criar sistemas robustos e escaláveis.

Este blog demonstra como usar o Amazon DynamoDB, um banco de dados NoSQL de valores-chave Serverless totalmente gerenciado, e o Amazon EventBridge, um barramento de eventos Serverless gerenciado, para implementar mensagens confiáveis para microsserviços usando o padrão de caixa de saída transacional.

As operações comerciais podem abranger vários sistemas ou bancos de dados para manter a consistência e a sincronização entre eles. Uma abordagem frequentemente usada em sistemas ou arquiteturas distribuídos em que os dados devem ser replicados em vários locais ou componentes é a gravação dupla. Em um cenário de gravação dupla, quando uma operação de gravação é executada em um sistema ou banco de dados, os mesmos dados ou eventos também acionam outro sistema em tempo real ou quase em tempo real. Isso garante que os dois sistemas sempre tenham os mesmos dados, minimizando as inconsistências de dados.

As gravações duplas também podem introduzir desafios de integridade de dados em sistemas distribuídos. A falha na atualização do banco de dados ou no envio de eventos para outros sistemas downstream após uma atualização inicial do sistema pode levar à perda de dados e deixar o aplicativo em um estado inconsistente. Uma abordagem de design para superar esse desafio é combinar gravações duplas com o padrão de caixa de saída transacional.

Desafios com gravações duplas

Considere um aplicativo de pedido de comida on-line para ilustrar os desafios da gravação dupla. Depois que o usuário envia o pedido, o serviço de pedidos atualiza o status do pedido em um armazenamento de dados persistente. A atualização do status do pedido também deve ser enviada aos serviços notify_restaurant e order_tracking usando um barramento de mensagens para comunicação assíncrona. Depois de atualizar com sucesso o status do pedido no banco de dados, o serviço de pedidos grava o evento no barramento de mensagens. O order_service executa uma operação de gravação dupla atualizando o banco de dados e publicando os detalhes do evento no barramento de mensagens para que outros serviços possam ler.

Essa abordagem funciona até que haja problemas na publicação do evento no barramento de mensagens. A publicação de eventos pode falhar por vários motivos, como um erro de rede ou uma interrupção no barramento de mensagens. Quando ocorrer uma falha, os serviços notify_restaurant e order_tracking não serão notificados sobre o evento de atualização do pedido, deixando o sistema em um estado inconsistente. A implementação do padrão de caixa de saída transacional com gravações duplas pode ajudar a garantir mensagens confiáveis entre sistemas após uma atualização do banco de dados.

Esta ilustração mostra um diagrama de sequência para um aplicativo on-line de pedidos de comida e os desafios da gravação dupla:

Sequence diagram

Visão geral do padrão de caixa de saída transacional

No padrão de caixa de saída transacional, um segundo armazenamento de dados persistente é introduzido para armazenar as mensagens enviadas. No exemplo do pedido de comida on-line, atualizar o banco de dados com os detalhes do pedido e armazenar as informações do evento na tabela da caixa de saída se torna uma única transação atômica.

A transação só é bem-sucedida ao gravar no banco de dados e na tabela da caixa de saída. Qualquer falha na gravação na tabela da caixa de saída reverte a transação. Em seguida, um processo separado lê o evento da tabela da caixa de saída e publica o evento no barramento de mensagens. Quando a mensagem estiver disponível no barramento de mensagens, ela poderá ser lida pelos serviços notify_restaurant e order_tracking. A combinação do padrão de caixa de saída transacional com gravações duplas permite a consistência dos dados em todos os sistemas e a entrega confiável de mensagens com o contexto transacional.

A ilustração a seguir mostra um diagrama de sequência para um aplicativo de pedidos de comida on-line com padrão de caixa de saída transacional para entrega confiável de mensagens.

Sequence diagram 2

Implementando o padrão de caixa de saída da transação

O DynamoDB inclui um recurso chamado DynamoDB Streams para capturar uma sequência ordenada por tempo de modificações em nível de item na tabela do DynamoDB e armazenar essas informações em um registro por até 24 horas. Os aplicativos podem acessar esse registro e visualizar os itens de dados como eles apareciam antes e depois de serem modificados, quase em tempo real.

Sempre que um aplicativo cria, atualiza ou exclui itens na tabela, o DynamoDB Streams grava um registro de stream com os principais atributos dos itens que foram modificados. Um registro de stream contém informações sobre uma modificação de dados em um único item em uma tabela do DynamoDB. O DynamoDB Streams grava registros de stream quase em tempo real e eles podem ser consumidos para processamento com base no conteúdo. A ativação desse recurso elimina a necessidade de manter uma tabela de caixa de saída separada e reduz a sobrecarga operacional e de gerenciamento.

O EventBridge Pipes conecta produtores de eventos a consumidores com opções para transformar, filtrar e enriquecer mensagens. O EventBridge Pipes pode se integrar ao DynamoDB Streams para capturar eventos de tabela sem escrever nenhum código. Não há necessidade de escrever e manter um processo separado para ler o stream. O EventBridge Pipes também suporta novas tentativas, e qualquer evento com falha pode ser roteado para uma fila de cartas mortas (DLQ) para análise e reprocessamento adicionais.

O EventBridge pesquisa fragmentos no stream do DynamoDB em busca de registros e invoca canais assim que os registros estão disponíveis. Você pode configurá-lo para ler registros do DynamoDB somente quando ele tiver coletado um tamanho de lote especificado ou a janela do lote expirar. O Pipes mantém a ordem dos registros do fluxo de dados ao enviar esses dados para o destino. Opcionalmente, você pode filtrar ou aprimorar esses registros antes de enviá-los a um destino para processamento.

Visão geral do exemplo

O diagrama a seguir ilustra a implementação do padrão de caixa de saída transacional com o DynamoDB Streams e o EventBridge Pipe. O Amazon API Gateway é usado para acionar uma operação do DynamoDB por meio de uma solicitação POST. A alteração no DynamoDB aciona um barramento de eventos do EventBridge por meio do Amazon EventBridge Pipes. Esse barramento de eventos invoca as funções do Lambda por meio de uma fila SQS, dependendo dos filtros aplicados.

Architecture overview

  1. Neste exemplo de implementação, o Amazon API Gateway faz uma chamada POST para a tabela do DynamoDB para atualizações do banco de dados. O Amazon API Gateway suporta operações CRUD para o Amazon DynamoDB sem a necessidade de uma camada computacional para chamadas de banco de dados.
  2. O DynamoDB Streams está ativado na tabela, que captura uma sequência ordenada por tempo de modificações em nível de item na tabela do DynamoDB quase em tempo real.
  3. O EventBridge Pipes se integra ao DynamoDB Streams para capturar os eventos e, opcionalmente, pode filtrar e enriquecer os dados antes de serem enviados para um destino compatível. Neste exemplo, os eventos são enviados para o Amazon EventBridge, que atua como um barramento de mensagens. Isso pode ser substituído por qualquer um dos alvos compatíveis, conforme detalhado nos destidos do Amazon EventBridge Pipes. O DLQ pode ser configurado para lidar com qualquer evento com falha, que pode ser analisado e repetido.
  4. Consumidores que ouvem o barramento de evento recebem mensagens. Opcionalmente, você pode distribuir e entregar os eventos a vários consumidores e aplicar filtros. Você pode configurar uma DLQ para lidar com quaisquer falhas e novas tentativas.

Pré-requisitos

  1. AWS SAM CLI, versão 1.85.0 ou superior
  2. Python 3.10

Implantando o aplicativo de exemplo

  1. Clone o repositório:
    git clone https://github.com/aws-samples/amazon-eventbridge-pipes-dynamodb-stream-transactional-outbox.git
  2. Vá para o diretório raiz do projeto e execute os seguintes comandos da CLI do AWS SAM:
    cd amazon-eventbridge-pipes-dynamodb-stream-transactional-outbox               
    sam build
    sam deploy --guided
    
  3. Insira o nome da sua pilha durante a implantação guiada. Durante o processo de implantação, selecione a opção padrão para todas as etapas adicionais.
    SAM deployment
  4. Os recursos são implantados.
    Testing the application

Testando o aplicativo

Quando a implantação estiver concluída, ela fornecerá a URL do API Gateway na saída. Você pode testar usando esse URL. Para testar o aplicativo, use o Postman para fazer uma chamada POST para o URL de produção do API Gateway:

Postman

Você também pode testar usando o comando curl:

curl -s --header "Content-Type: application/json" \
  --request POST \
  --data '{"Status":"Created"}' \
  <API_ENDPOINT>

Isso produz a seguinte saída:

Expected output

Para verificar se os detalhes do pedido estão atualizados na tabela do DynamoDB, execute esse comando para realizar uma operação de verificação na tabela.

aws dynamodb scan \
    --table-name <DynamoDB Table Name>

Lidando com falhas

O DynamoDB Streams captura uma sequência ordenada por tempo de modificações em nível de item na tabela do DynamoDB e armazena essas informações em um registro por até 24 horas. Se o EventBridge não estiver disponível para leitura do DynamoDB Stream devido a uma configuração incorreta, por exemplo, os registros ficarão disponíveis no log por 24 horas. Depois que o EventBridge é reintegrado, ele recupera todos os registros não entregues das últimas 24 horas. Para problemas de integração entre o EventBridge Pipes e o aplicativo de destino, todas as mensagens com falha podem ser enviadas ao DLQ para reprocessamento posterior.

Limpando

Para limpar seus recursos baseados na AWS, execute o seguinte comando da CLI do AWS SAM, respondendo “y” a todas as perguntas:

sam delete --stack-name <stack_name>

Conclusão

A comunicação confiável entre serviços é uma consideração importante no design de microsserviços, especialmente quando se trata de gravações duplas. A combinação do padrão de caixa de saída transacional com gravações duplas fornece uma maneira robusta de melhorar a confiabilidade das mensagens.

Este blog demonstra um padrão de arquitetura para enfrentar o desafio das gravações duplas combinando-o com o padrão de caixa de saída transacional usando o DynamoDB e o EventBridge Pipes. Essa solução fornece uma abordagem sem código com o AWS Managed Services, reduzindo a sobrecarga operacional e de gerenciamento.

Para obter mais recursos de aprendizado Serverless, visite Serverless Land. Saiba mais sobre o DynamoDB:

Biografia do Autor

Sangram Sonawane é arquiteto de soluções sênior.

 

 

 

 

 

Biografia do tradutor

Daniel Abib é Enterprise Solution Architect na AWS, com mais de 25 anos trabalhando com gerenciamento de projetos, arquiteturas de soluções escaláveis, desenvolvimento de sistemas e CI/CD, microsserviços, arquitetura Serverless & Containers e segurança. Ele trabalha apoiando clientes corporativos, ajudando-os em sua jornada para a nuvem.

https://www.linkedin.com/in/danielabib/