Event Flow
Um sistema .NET distribuído com duas faces, o produto que o cliente usa e a maquinaria embaixo reagindo em tempo real.
- .NET Aspire
- MassTransit
- RabbitMQ
- SignalR
- React
Duas visões de um sistema
Visão do cliente é o produto: um pedido aparece na hora como pendente e acompanha até assentar. Se o pagamento é recusado, a falha é tratada na interface. Se está só lento — porque o provedor não responde e a mensagem está sendo retentada — a interface diz isso, com o número da tentativa.
Visão do sistema são os mesmos eventos como maquinaria: quatro serviços em cadeia, cada nó acendendo quando uma mensagem chega, latência e profundidade de fila reais.
A maioria das demos de sistemas distribuídos mostra só a segunda. Mostrar as duas é o ponto: o diagrama é a razão de a experiência do cliente se manter de pé quando um serviço cai.
Falha, de propósito
Existe um botão que derruba o serviço de pagamentos. Os pedidos continuam sendo aceitos; a mensagem falha e o MassTransit retenta com backoff exponencial (~1,2 a 8,8s) enquanto a fila cresce no RabbitMQ. Traga os pagamentos de volta dentro de vinte segundos e a mensagem passa na tentativa seguinte. Deixe assim e, na sexta tentativa, ela cai em payments-authorize_error, o pedido passa a dizer “travado, nada foi cobrado”, e aparece um botão de replay — que dedupica, porque cada consumidor grava idempotência na mesma transação do próprio trabalho.
Os quatro padrões (outbox transacional, idempotência do consumidor, retry com backoff exponencial, dead-letter e replay) estão cada um num arquivo pequeno, com o raciocínio ao lado do código.
Medido, não afirmado
Todo número na tela vem de algum lugar real: a latência do salto é a diferença entre timestamps de envio e recebimento; as profundidades de fila vêm da API do RabbitMQ; o estado de cada serviço é a resposta /health daquele serviço — o mesmo contrato de cinco campos usado no resto do site, gerado em C# e TypeScript a partir de um único JSON Schema.
Por isso, derrubar os pagamentos muda o uptime reportado e o status na home do site, sem nada ligado manualmente para isso acontecer.
Duas coisas são simuladas e marcadas no código: a ida e volta a um provedor de pagamento, e a chamada a um armazém. O resto, entre o navegador e essas duas linhas, é real.
Sobre o broker
RabbitMQ, hospedado num contêiner ao lado dos serviços e orquestrado com .NET Aspire — não custa nada rodar.
O trabalho de produção é em Azure Service Bus. Os padrões atravessam sem mudança, porque outbox, idempotência, backoff e dead-letter são agnósticos de transporte por construção; mudaria só a linha que nomeia o transporte. O Service Bus ainda dá sessions e entrega agendada no próprio broker, o que simplifica a reentrega adiada.
p95 ao vivo -uptime -