Cenário:
Temos um serviço de pagamento que consome dados de duas filas:
clients-processor
: fila com dados de clientes para cadastrar
payment-processor
: fila com dados de um pagamento para ser processado
Esse serviço processa os pagamentos, porém ele só processa pagamentos de clientes que estão cadastrados.
Problema:
Como tratar o problema de race condition quando um evento de pagamento é recebido primeiro que o evento de cadastro de clientes (sem utilizar bancos de dados). Para simplificar mais temos a premissa que o evento de cadastro de cliente sempre será recebido.
A solução:
clients-processor
: Uma fila para evento de cadastro de clientes
payment-processor
: Uma fila para evento de pagamentos
payment-reprocessor
: Uma fila para reprocessar eventos de pagamentos utilizando o plugin delayed_message_exchange
do RabbitMQ
Quando um evento de pagamento é recebido e o cliente ainda não está cadastrado, aumentamos o valor do delay
da mensagem em 1 segundo
. A mensagem é então encaminhada para a fila de reprocessamento. Em algum momento, quando um cliente for efetivamente cadastrado, o pagamento correspondente será processado.
Para exemplificar melhor, o fluxo grama abaixo mostra a abordagem utilizada:
Exemplo:
Crie uma aplicação com Golang + RabbitMQ para implementar toda abordagem comentada acima, você pode encontrá-la no meu GitHub, e lá terá as instruções para rodar.
Para o exemplo, vamos enviar duas mensagens, uma com o pagamento e outra com o novo cliente.
Ao receber um pagamento de um cliente com o ID 1, o pagamento não vai ser processado, a mensagem é enviada para uma fila e o delay vai aumentando, até que a mensagem de cadastro do cliente é recebida, no proximo recebimento do pagamento ele será processado e a operação finaliza.
Vídeo da aplicação:
Bom é isso, espero que tenha gostado da estratégia, sobre a aplicação, a mesma foi escrita em Golang, mas mesmo que você não desenvolva com Go, é uma aplicação muito simples e acredito que não terá problema em entender o código.
Top comments (0)