Arquitetura de liquidações relâmpago: absorva picos sem vender estoque inexistente
Uma oferta concorrida sincroniza milhões de ações: abrir a página, conferir disponibilidade, iniciar checkout e tentar pagar. A meta de engenharia não é tornar cada dependência infinitamente rápida; é liberar trabalho no ritmo que o fluxo de compra consegue concluir, proteger a autoridade do estoque e dar um desfecho recuperável a cada pedido aceito.
Publicado em 28 de setembro de 202615 min de leituraControle de tráfego e confiabilidade no checkout
Escala de navegação não é capacidade de compra
Coloque imagens, descrição e dados de catálogo seguros para cache na CDN. Preço personalizado, estado da conta, promessa de estoque e decisões de checkout devem continuar nas fontes autoritativas. A CDN absorve leituras repetidas, mas não torna um processador de pagamentos ou uma linha concorrida do inventário capaz de aceitar escritas ilimitadas. Um número de estoque em cache é informativo, não uma reserva.
Modele a demanda antes que ela alcance o caminho transacional escasso
1 / BordaCache de catálogo; filtro de abuso e proteção da origem.
2 / EntradaSala de espera ou limites liberam um fluxo controlado de clientes.
3 / CheckoutLimite concorrência e crie uma única tentativa durável por pedido.
4 / EstoqueReserve unidades atomicamente, com responsável e prazo de expiração.
5 / PagamentoAutorize com chave idempotente estável e reconcilie o resultado.
A sala de espera muda a taxa de chegada, não a capacidade do backend. Defina a liberação com base em testes de carga e limites dos serviços dependentes; acompanhe idade da fila, desistências e conversão. Uma fila limitada precisa de prazo e de uma resposta clara quando está cheia. Sem limites, o excesso só muda de lugar: memória, armazenamento ou uma tempestade de retentativas.
O estoque precisa ter uma fonte de verdade
Modele quantidades disponíveis, reservadas e comprometidas. A reserva deve nascer de uma operação atômica na autoridade do inventário, como uma atualização condicional que só funciona se ainda houver unidades suficientes. Um lock distribuído, sozinho, não é um modelo de estoque: leases expiram, clientes pausam e o lock não registra qual pedido é dono da unidade.
Associe pedido, quantidade, horário de criação e validade a cada reserva. No sucesso do pagamento, converta-a em estoque comprometido uma única vez. Em recusa, cancelamento ou expiração conforme a política, libere-a por uma transição idempotente. Um reconciliador deve localizar reservas vencidas e corrigir estados travados. Particionar quantidades pode reduzir contenção, mas exige reconciliação explícita entre partições para não exceder o total.
Retentativa de pagamento precisa de identidade e estado
Timeout de rede não prova que a cobrança falhou: o provedor pode ter concluído a operação sem que a resposta tenha chegado. Persista a tentativa e reutilize a mesma chave de idempotência nas retentativas daquela operação lógica, com parâmetros iguais. Não crie uma chave nova porque o cliente perdeu a resposta; primeiro consulte ou reconcilie a tentativa existente. Separe o estado do pedido do estado de transporte do provedor.
Webhooks podem ser duplicados ou chegar fora de ordem. Persista os IDs dos eventos, torne os handlers idempotentes, valide assinaturas e permita apenas transições de estado válidas. Um outbox, escrito na mesma transação local do pedido, permite publicar depois se a gravação no banco funcionar e a publicação falhar. Banco e broker não passam a compartilhar um commit atômico por causa disso.
Orquestre a compra como uma saga
Estoque, pedido e pagamento normalmente não compartilham uma transação ACID entre serviços. Modele o checkout como uma máquina de estados durável: criar pedido, reservar estoque, pedir autorização e confirmar. Se houver recusa, libere a reserva e encerre o pedido. Se a autorização ocorrer e uma etapa posterior falhar, estorne ou cancele conforme o ciclo de vida do provedor e a política do negócio. Compensar é executar uma nova ação, não voltar no tempo; essa ação também falha e precisa de retentativa, alerta e reconciliação.
Falha observada
Reação arriscada
Recuperação controlada
Timeout no checkout
Criar outro pedido com identidade nova.
Consultar a tentativa durável e devolver o estado atual.
Resposta do pagamento ambígua
Assumir recusa ou cobrar de novo.
Repetir com a mesma chave e reconciliar com o provedor.
Webhook repetido
Alterar estoque e pagamento duas vezes.
Deduplicar evento e validar transição.
Reserva vence
Prender estoque ou liberar pedido já pago.
Definir prazo explícito e conferir o estado do pagamento antes da liberação.
Consumidor atrasado
Deixar uma fila ilimitada crescer.
Aplicar backpressure, retenção limitada, admissão e resposta clara.
Observe a jornada do cliente, não apenas a CPU
Meça chegadas admitidas e recusadas, espera, conversão no checkout, sucesso das reservas, idade delas, estoque disponível versus retido, latência de autorização, tentativas ambíguas, duplicatas de webhook, atraso da fila e falhas de compensação. Segmente por campanha, produto e região sem inserir dados pessoais nos rótulos. Acione alertas para impacto ao cliente e estados travados, não para cada retentativa transitória.
Antes da campanha, reproduza tráfego realista em ambiente parecido com produção. Inclua disputa por item popular, commits lentos, timeout no provedor, webhooks duplicados e fora de ordem, reinício de workers e retomada após backlog. Prepare um interruptor para parar novas admissões e ainda permitir a reconciliação dos pedidos aceitos. Informe posição, validade e estado ao cliente: atualizar a página repetidamente só aumenta a carga.
Em resumo
Uma venda relâmpago confiável começa com um limite de capacidade conhecido. Faça cache do que for seguro, admita trabalho transacional na velocidade que o sistema suporta, reserve estoque atomicamente e torne as transições de pedido e pagamento duráveis e idempotentes. Filas suavizam picos; não apagam gargalos. Testes de carga, estados claros e reconciliação transformam falhas parciais em um processo operável.