Olá! Como estão? Sejam muito bem-vindes a este módulo. Hoje, vamos falar sobre um tema que está no centro de praticamente todos os sistemas modernos: arquiteturas distribuídas e integrações de sistemas. Vamos construir sistemas que se comunicam, escalam e sobrevivem a falhas. Isso não é poesia; é o cotidiano de quem trabalha com software em produção. Ao longo deste percurso, vamos abordar temas como sistemas distribuídos, integrações, escalabilidade e resiliência. Vamos começar?
Antes de entrarmos no conteúdo, vou me apresentar rapidamente. Eu sou Fernando Silva, arquiteto principal de soluções na Gatinet, atuando com soluções orientadas por dados. Publiquei alguns artigos na revista Net Magazine, sou conferencista no TDC, professor em pós-graduação em Engenharia e Arquitetura de Software e tenho mais de 20 anos de experiência. Durante este módulo, estaremos juntos neste percurso.
Antes de mergulharmos, vamos apresentar uma visão holística do que vamos construir e aprender hoje. Este não é um tema isolado. Trata-se de uma progressão na qual cada tópico é a continuação do anterior.
Vamos começar pela base. Comunicação síncrona e comunicação assíncrona parecem temas simples, mas é aqui que residem grande parte das decisões arquiteturais que raramente questionamos e que deveríamos questionar. Essa escolha pode determinar o nível de acoplamento, a resiliência e o desempenho do sistema como um todo.
Após explorarmos comunicação assíncrona, vamos analisar eventos, mensageria e arquitetura orientada a eventos, identificando quando os serviços deixam de se chamar diretamente e passam a reagir a fatos que ocorrem entre eles.
Aqui vamos abordar o barramento de eventos, como Kafka, além de produtores e consumidores. Este é o coração dos sistemas modernos em larga escala.
Ao distribuir tudo, acabamos abrindo mão de algo; é nesse ponto que entra a consistência eventual. Precisamos entender que os dados podem ficar consistentes em algum momento, passando a trocar disponibilidade por escalabilidade, e como o negócio precisa estar ciente disso.
Em seguida, trataremos de um tema que parece um detalhe técnico, mas quebra muitos sistemas em produção: idempotência e ordenação, mensagens duplicadas e garantias. A questão não é apenas conhecer esses conceitos, mas saber como lidar com eles.
Com isso, avançamos para a integração entre sistemas, o problema real de empresas que possuem dezenas de sistemas legados e modernos que precisam se comunicar entre si.
Então chegamos às falhas distribuídas, a parte que ninguém quer considerar, mas que é a única certeza em produção. A rede vai falhar, um serviço pode cair, e a questão é quando isso ocorrerá e como o sistema sobreviverá a essas falhas.
Fechamos o ciclo discutindo a arquitetura orientada à integração, onde tudo isso se transforma em um projeto consciente: não a integração como remendo, mas como parte do desenho desde o início.
Cada aula prepara o terreno para o tema seguinte e, ao final, teremos um sistema robusto, escalável, resiliente e protegido contra falhas.
Vamos começar definindo o que são sistemas distribuídos.
Nós gostamos muito da definição de Tanenbaum, segundo a qual um sistema distribuído é um conjunto de computadores independentes que se apresenta à pessoa usuária como um sistema único e coerente.
Em outras palavras, quando a pessoa usuária acessa uma aplicação, uma API (Interface de Programação de Aplicações), um serviço, não sabe que, por trás, existem 10, 20, 30 serviços em comunicação, e nem precisa saber disso. O desafio recai sobre nós, nas áreas de arquitetura e desenvolvimento.
Assim, identificamos três características centrais.
Podemos ter múltiplos processos e serviços em execução em várias máquinas totalmente diferentes, com comunicação pela rede. Tudo passa pela rede, e a rede pode falhar. Inclusive, existem as oito falácias da computação distribuída, sobre as quais nós vamos falar mais adiante.
Nesse cenário, não há memória compartilhada, não há estado global, nem um ponto único de acesso: cada nó, cada máquina de computação opera em seu próprio contexto.
Para completar, há a concorrência: vários processos ocorrendo ao mesmo tempo, sem coordenação central. À primeira vista isso parece atraente, mas traz uma complexidade muito grande. É exatamente por isso que precisamos conhecer alguns padrões.
Aula 1 — Comunicação síncrona e assíncrona
Como os serviços se comunicam entre si? Esta é uma decisão muito importante de arquitetura. Frequentemente tomamos essa decisão no automático, sem considerar as consequências. Parece simples: um serviço precisa chamar outro, então faz a chamada. Mas como essa chamada é feita? E o que acontece se o serviço estiver indisponível ou demorar demais para responder? É isso que vamos entender ao longo deste percurso sobre comunicações.
Quando um serviço precisa de informações de outro serviço ou processo, há duas opções fundamentais, e essa decisão vai muito além do que parece à primeira vista. A primeira é a comunicação síncrona: esperar a resposta. O serviço A chama o serviço B e bloqueia o fluxo de execução até que o outro serviço responda. É simples e direto: fazemos a pergunta e esperamos a resposta.
A segunda opção é enviar e continuar; é o que chamamos de comunicações assíncronas. O serviço envia uma mensagem a um intermediador, uma API (Interface de Programação de Aplicações), um broker (intermediador), um barramento de eventos e segue seu fluxo. A resposta chegará em algum momento — ou pode nem chegar —, e o sistema precisa saber lidar com isso. Essa parece uma escolha apenas técnica, mas não é só isso. Essa decisão determina três aspectos que estão no coração de qualquer arquitetura: desempenho, acoplamento e resiliência.
Definir corretamente o tipo de comunicação é extremamente importante. Definir mal é problemático. Criar uma comunicação síncrona onde deveria ser assíncrona pode impedir a escalabilidade; uma falha em cadeia pode derrubar tudo. O inverso também é verdadeiro: fazer uma comunicação assíncrona onde deveria ser síncrona adiciona complexidade desnecessária e pode comprometer a consistência de que o negócio tanto precisa.
Vamos detalhar a comunicação síncrona. É a que a maioria de nós aprendeu primeiro: o serviço A chama o serviço B e fica esperando a resposta. Exemplos clássicos incluem chamadas HTTP, uso de RPC, GraphQL ou SOAP. Entre as vantagens, temos implementação simples, resposta imediata, facilidade de depuração e uma trilha de rastreamento linear. Entre as desvantagens, há o acoplamento temporal: se o serviço B estiver fora do ar, o serviço A não funciona corretamente. Podemos ter falhas em cascata: uma lentidão no serviço B ocasiona lentidão no serviço A e, com mais serviços encadeados, ocorre uma cascata de falhas. Também há aumento de latência: cada microsserviço pode ter uma latência pequena, mas a soma de todas pode resultar em uma latência muito elevada.
Não estamos afirmando que a comunicação síncrona seja ruim; ela tem seu lugar, mas exige que compreendamos seus custos. Um exemplo é a consulta de saldo bancário. Pensemos: ao abrir o aplicativo do banco e clicar em “ver saldos”, o aplicativo chama um serviço (uma API), esse serviço consulta a base de dados, e observamos o carregamento sabendo que algo está acontecendo enquanto esperamos a resposta. Esse é o processo: ficamos bloqueados, e o aplicativo não faz mais nada até obter a resposta. Isso faz sentido, pois precisamos do número naquele momento; precisamos conhecer o saldo naquele instante. Não há como mostrar um saldo provável ou uma resposta que chegará depois; precisamos fazer a solicitação, receber a resposta e aguardar até que o saldo esteja disponível na tela.
Agora, sobre comunicações assíncronas: aqui o serviço A envia uma mensagem; pode enviá-la ao serviço B ou a um intermediador/barramento de eventos, como Apache Kafka, RabbitMQ, Amazon SQS ou Azure Service Bus, e segue em frente. O serviço B consome essa mensagem no seu próprio ritmo. A grande vantagem é o desacoplamento real: A e B não precisam estar ativos ao mesmo tempo; se o serviço B cair, as mensagens ficam no barramento de eventos aguardando. Outras vantagens incluem alta resiliência e escalabilidade horizontal: podemos adicionar mais consumidores para ler essas mensagens.
Tudo, porém, tem seu preço. A comunicação assíncrona traz maior complexidade, pois introduz componentes adicionais, como um broker (intermediador), consumidores e filas. Também exige a implementação de padrões de novas tentativas e de backoff (recuo), além de uma boa observabilidade.
Há outro custo: a consistência eventual; os dados ficarão temporariamente desatualizados, portanto, nossa arquitetura e nosso processo de negócio devem permitir isso; além disso, depurar torna-se mais difícil.
Um exemplo assíncrono: um pedido no iFood. Quando fazemos um pedido, aparece a tela “pedido confirmado” e pronto; o aplicativo já mostra a confirmação, mas talvez o restaurante ainda não tenha aceitado, a pessoa entregadora ainda não tenha sido notificada e o sistema de pagamentos ainda esteja processando em segundo plano. Tudo isso ocorre de forma assíncrona, em paralelo, enquanto muitas vezes já fechamos o aplicativo e vamos fazer outras coisas. Imagine se o iFood esperasse a confirmação do restaurante para exibir a tela de confirmação em uma sexta-feira à noite; como o restaurante está cheio, essa resposta pode levar 30 segundos, 1 minuto, e ficaríamos apenas olhando a tela. O sistema não escalaria nesse formato.
Esses exemplos são importantes porque mostram que uma escolha técnica dependerá muito da decisão de negócio. Precisamos fazer um equilíbrio entre comunicações síncronas e assíncronas:
Regra prática: usar a comunicação síncrona quando precisamos de resposta agora, imediatamente; e usar a assíncrona quando podemos processar depois e quando precisamos escalar. Em teoria é simples; na prática, veremos nuances entre esses dois processos.
Quando usar cada uma? Vamos consolidar com exemplos do mundo real.
Usar a comunicação síncrona quando a resposta imediata for requisito do negócio. Autenticação: a pessoa usuária faz login e precisa saber agora se entrou ou não; não vamos usar a comunicação assíncrona para autenticação. Lembremos o exemplo da consulta de saldo: a pessoa cliente quer ver quanto tem na conta; quando o processo precisar de resposta imediata, seguimos para um cenário, para uma arquitetura síncrona.
Usar a comunicação assíncrona quando o volume for alto e imprevisível. Na gestão de logs (registros), por exemplo, são milhares de eventos por segundo: ninguém vai esperar a resposta de um registro de log. No processamento de pedidos em e-commerce (comércio eletrônico), confirmamos à pessoa cliente que recebemos o pedido e, em seguida, processamos em segundo plano outros passos, como redução de estoque, sistema de pagamentos, envio de comunicações para a área de logística e para a área de entrega, criação de pipelines (fluxos) de dados, processamento por lotes, transformações e enriquecimentos. Nesses cenários, optamos por uma arquitetura orientada a comunicações assíncronas. Percebamos: nos casos síncronos, o negócio precisa da resposta para continuar; nos assíncronos, o negócio pode continuar sem essas respostas.
Quais são os custos ocultos?
Custos ocultos da comunicação síncrona: uma chamada lenta bloqueia todo o serviço, por exemplo, um timeout (tempo de espera excedido). Em caso de falha, todos tentam ao mesmo tempo, e precisamos adotar alguns padrões para evitar um caos total. Quando há bloqueio ou ausência de resposta, precisamos tratar a comunicação com um padrão de nova tentativa e um padrão de circuit breaker (disjuntor de circuito). Uma falha pode se propagar por toda a cadeia; é comum vermos isso acontecer, e é difícil de tratar.
Custos ocultos da comunicação assíncrona: os dados podem ficar temporariamente desatualizados (consistência eventual). Mensagens podem falhar e se acumular; por exemplo, podemos enviar mensagens para uma fila com prazo. Garantir a ordem correta dos eventos é muito difícil; se precisarmos de processamento em ordem, esses casos ficam mais complexos. Rastrear para onde um evento foi, depurar e traçar essas chamadas também se torna mais trabalhoso.
Não existe almoço grátis: cada escolha tem seu custo. Uma boa pessoa arquiteta não é a que escolhe “a melhor” opção em abstrato, mas a que considera claramente o custo do que está escolhendo e, consequentemente, entrega valor para o negócio.
O curso Sistemas distribuídos: integrações resilientes e orientadas a eventos possui 165 minutos de vídeos, em um total de 41 atividades. Gostou? Conheça nossos outros cursos de Arquitetura de Software em Back-end, ou leia nossos artigos de Back-end.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
O Plano Plus evoluiu: agora com Luri para impulsionar sua carreira com os melhores cursos e acesso à maior comunidade tech.
2 anos de Alura
Matricule-se no plano PLUS 24 e garanta:
Jornada de estudos progressiva que te guia desde os fundamentos até a atuação prática. Você acompanha sua evolução, entende os próximos passos e se aprofunda nos conteúdos com quem é referência no mercado.
Back-end, Dados, Front-end, DevOps, Mobile, Gestão & Negócios, UX & Design, Cibersegurança, Cloud, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
Acesso à inteligência artificial da Alura.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Catálogo de tecnologia para quem é da área de Marketing
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
20% de desconto na Pós Tech
Luri Vision chegou no Plano Pro: a IA da Alura que enxerga suas dúvidas, acelera seu aprendizado e conta também com o Alura Língua que prepara você para competir no mercado internacional.
2 anos de Alura
Todos os benefícios do PLUS 24 e mais vantagens exclusivas:
Acesso ao catálogo da Casa do Código e leitura dentro da plataforma
Chat, busca, exercícios abertos, revisão de aula, geração de legenda para certificado.
Modo entrevista - Pratique situações reais e evolua com feedback personalizado
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Para quem quer atingir seus objetivos mais rápido: Luri Vision ilimitado, vagas de emprego exclusivas e mentorias para acelerar cada etapa da jornada.
2 anos de Alura
Todos os benefícios do PRO 24 e mais vantagens exclusivas:
Lives CareerUp: eventos exclusivos com foco em empregabilidade e carreira
Mentorias de carreira: 2 encontros individuais com mentores do Talent Lab
Conecte-se ao mercado com mentoria individual personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.