Por que a arquitetura parece boa até o primeiro incidente?
Todo castelo parece firme no slide. Até vir a primeira chuva.
Senta aqui um minutinho. Vamos conversar com calma sobre um assunto que vive escondido atrás de boas intenções e diagramas bonitos: a distância brutal entre a arquitetura projetada e a arquitetura executada.
No PowerPoint, no draw.io, tudo funciona.
Os serviços são independentes,
a fila processa eventos com elegância,
os bancos são replicados,
os fluxos têm setinhas azuis,
e os quadradinhos têm nomes que até soam inteligentes.
Mas aí vem a chuva.
E a chuva, nesse mundo nosso, se chama incidente em produção.
É nesse momento que o castelo vira barraco:
A fila não tem dead letter. 🕳
Ou seja, mensagens que falham ao serem processadas ficam presas eternamente, tentando, tentando, tentando... até travar a fila inteira. Você projetou um sistema assíncrono, mas esqueceu que o “não processado” também precisa de um lugar pra ir. Um Dead Letter Queue (DLQ) é onde você joga essas mensagens problemáticas. Não é luxo — é sobrevivência.
O retry gera efeito cascata. 🔁
Retry automático sem controle é como um funcionário insistente que tenta entregar o mesmo pacote 50 vezes por minuto. Agora multiplica isso por 10 serviços em cadeia — é assim que nascem os incêndios em produção. Sem backoff, sem limite, sem rastreabilidade.
O “serviço autônomo” depende do deploy do outro. 🧷
Você achava que era microserviço, mas era só um microacoplamento distribuído.
Na prática:
Serviço A não sobe sem o B.
O schema do banco do C afeta o A.
E o deploy do D precisa da versão nova do E.
Ou seja, a arquitetura é distribuída no papel — e monolítica no trauma.
Ninguém pensou em observabilidade de verdade 👻
Sem logs estruturados, tracing, métricas e dashboards, seu sistema se torna um buraco negro: tudo entra, mas nada sai.
Ou pior: o que sai é ruído.
E ruído em momento de incidente é o que separa um rollback rápido de uma madrugada em claro.
Agora, vamos dar nome aos vilões invisíveis que vivem nos slides ignorados…
Latência: O tempo que o mundo real cobra 🐢
Latência é o tempo entre pedir algo e receber a resposta.
No mundo real, cada chamada de API, cada leitura de banco, cada chamada de fila custa milissegundos que somam segundos.
O problema?
Na arquitetura de slide, tudo parece instantâneo.
Mas em produção, três chamadas síncronas em sequência já causam lentidão percebida.
Adicione redes instáveis, picos de tráfego e load balance... e pronto: você tem um delay que a arquitetura nunca considerou.
Dependência circular: o loop da dor 🔄
Dependência circular acontece quando dois ou mais serviços dependem uns dos outros para funcionar.
Exemplo:
O serviço de pagamentos consulta o de estoque,
O de estoque consulta o de pedidos,
E o de pedidos chama o de pagamentos.
Resultado?
Um loop de dependência que trava tudo.
Basta um ponto cair para o resto virar refém, é um castelo de cartas, não uma arquitetura resiliente.
Fallback: o paraquedas que ninguém lembra de dobrar
Um fallback é uma alternativa segura para quando algo dá errado.
Se o serviço de sugestão de produto falha, mostre os mais vendidos.
Se o sistema de recomendação cai, mostre uma lista genérica.
Parece simples, né? Mas a maioria dos sistemas esquece de definir esse "plano B".
Resultado? Um erro vira erro em cadeia.
Porque você não disse ao sistema o que fazer quando as coisas falham. E elas vão falhar. Sempre.
Ignorar o mundo real não o torna menos real
Arquitetura de verdade não pode viver só no ideal.
Ela precisa levar em conta o que é feio, imprevisível, imperfeito.
Precisa assumir que:
o serviço pode cair,
o dado pode atrasar,
a request pode não chegar,
e o ser humano pode errar (spoiler: vai errar).
Se seu design só funciona em cenário feliz, então não é arquitetura — é ficção.
E o que fazer com isso?
Simule falhas antes que o mundo real as provoque.
Projete com humildade, aceitando que o caos virá.
Documente as exceções, não só os caminhos perfeitos.
E, acima de tudo, teste o que você desenhou como se fosse um ataque, não um desfile.
Arquitetura bonita não é a que impressiona no workshop.
Tá mas não para por aqui, vamos continuar a mergulhar mais nesse assunto.
Falta de Simulação de Falhas🔥
“Arquitetura resiliente que nunca foi testada... não é arquitetura, é aposta.”
A gente fala bonito: "nossa arquitetura é resiliente, distribuída, com fallback, retry, failover automático..."
Mas me responde uma coisa com sinceridade:
👉🏻 Você já testou ela falhando?
👉🏻 Já desligou um serviço de propósito pra ver o que acontece?
👉🏻 Já colocou a fila em sobrecarga?
👉🏻 Já cortou a conexão com o banco pra simular um caos real?
Porque se não fez nada disso...
Desculpa, mas o que você tem não é resiliência… é esperança fantasiada de arquitetura.
Arquitetura à prova de slides, mas não de incidentes ☄️
Na teoria, tá tudo lá:
Retry automático ✔️
Fallback genérico ✔️
Circuit breaker ✔️
Timeout configurado ✔️
Mas sem teste de verdade, esses itens são só check de planilha. Na prática:
O retry tenta
5x
e dobra a cargaO fallback nunca foi implementado direito
O timeout é de 30 segundos e trava tudo antes de cair
E o circuito? Nunca abriu porque ninguém sabia configurar
Sem chaos testing, você está jogando dados com a produção
Chaos testing1 não é maluquice. É maturidade.
É quando você, intencionalmente, quebra seu sistema em condições controladas pra ver se ele:
Se recupera,
Degrada com elegância,
Ou simplesmente… cai e te leva junto.
Se o seu sistema nunca passou por estresse real, ele não foi validado.
E o problema é: quem vai validá-lo, inevitavelmente, será o usuário final.
E ele não abre ticket… ele vai para o concorrente.
Falta retry. Falta fallback. Falta timeout.
Falta, principalmente, responsabilidade com a experiência real.
Você não pode esperar que tudo funcione sempre.
Você tem que assumir que as coisas vão dar errado.
E preparar o sistema para isso.
Retry sem backoff vira ataque de negação de serviço contra você mesmo.
Fallback sem contexto vira gambiarra disfarçada de proteção.
Timeout mal configurado transforma lentidão em paralisia.
A arquitetura nunca passou pelo que os usuários passam
Sabe aquele botão que o usuário clica e nada acontece por 10 segundos?
Ele tá vendo o reflexo de uma decisão sua.
De um timeout mal pensado.
De uma dependência não isolada.
De um retry que insiste onde não devia.
Se a experiência de falha do sistema não foi pensada,
o usuário vira cobaia do caos.
E quando o usuário sofre, a arquitetura fracassou.
O que dá pra fazer agora?
Implemente falhas controladas no ambiente de staging.
Use ferramentas como Chaos Monkey, Toxiproxy, scripts simples que derrubam serviços.Teste os circuit breakers.
Um circuit breaker que nunca dispara é um alarme de incêndio desligado.Simule falhas de rede, filas congestionadas, indisponibilidade de banco.
Documente o que deve acontecer quando tudo dá errado.
Não é só sobre "quando funciona", mas "quando falha, o que o sistema faz?"Treine o time de desenvolvimento pra pensar em falhas como parte do fluxo.
Porque a arquitetura não é o caminho feliz — é a rota de emergência.
Na engenharia de software, o caos não é um se, é um quando.
E o seu sistema tem duas opções:
Ou ele resiste ao caos,
Ou ele é parte dele.
Agora meu querido leitor, vamos conversar sobre autonomia…
A Autonomia que Era Só no Papel
“Microserviços prometem independência. Entregam dependência com fila.”
Deixa eu te perguntar uma coisa, com carinho mas sem anestesia:
Você tem microserviços mesmo?
Ou o que você tem é um monolito quebrado em pedaços, onde cada pedaço só funciona se os outros estiverem de pé?
Porque se você precisa de:
deploy coordenado entre 4 squads,
reunião no Slack pra decidir a ordem do rollout,
um cron job2 misterioso pra passar dado de um serviço pro outro,
e um pipeline travado porque o schema do outro serviço mudou...
Desculpa. Isso não é independência. Isso é acoplamento distribuído com marketing de arquitetura.
📌 Sam Newman enfatiza que um microserviço deve ser capaz de ser desenvolvido, testado e implantado de forma independente. Se o time precisa coordenar mudanças com outros times, a independência foi comprometida.
“A implantabilidade independente é o teste decisivo para microsserviços.” — Sam Newman
A promessa que vendeu sonhos...
A ideia dos microserviços é linda na teoria:
Cada serviço com seu time, seu ciclo de vida, seu banco.
Deploys independentes.
Domínios bem separados.
Redução de blast radius.
Time dono do serviço = time dono do negócio.
Mas na prática... a realidade chega gritando:
"O serviço A só sobe se o serviço B estiver online."
"Precisa versionar o contrato do serviço X porque Y usa um endpoint que foi renomeado."
"O time de faturamento não pode subir porque depende da versão nova do catálogo."
Resultado? Você trocou acoplamento de código por acoplamento de runtime.
📌 Martin Fowler já alertava sobre isso desde o início da popularização dos microserviços, chamando atenção para o “Design por divisão técnica”, que fragmenta sistemas sem pensar nos fluxos de negócios reais, gerando mais dependências do que isolamentos.
“Muitas equipes começam decompondo por camadas ou responsabilidades técnicas, esse é um caminho rápido para um monólito distribuído.”
🔄 Acoplamento via banco, API, cron job oculto
Você acha que os serviços são independentes…
Mas um depende dos dados do outro, lendo direto do banco alheio.
Ou chama endpoints síncronos sem fallback.
Ou roda um cron obscuro que sincroniza dados em silêncio — até o dia que ele falha e ninguém sabe por onde começar.
Isso não é autonomia.
É fragilidade com roupa bonita.
📌 Sam Newman alerta que o compartilhamento direto de banco de dados entre serviços é uma das violações mais perigosas da filosofia de microserviços.
“Os serviços não devem compartilhar bancos de dados. Isso introduz um acoplamento rígido e quebra o encapsulamento.” — Sam Newman
E não para por aí. Charity Majors, cofundadora da Honeycomb (uma das maiores vozes sobre observabilidade), vai além:
“Distribuir um sistema não torna ele melhor — só mais difícil de entender. Aumenta o número de lugares onde ele pode falhar.”
— Charity Majors
🔄 Rollbacks em cadeia, deploys sincronizados
Sam Newman, no livro "Building Microservices", já deixava claro:
“Se você não consegue implantar um serviço de forma independente, então ele não é realmente um microsserviço.”
E ele continua batendo nessa tecla em entrevistas e no Twitter até hoje:
Deploy independente é o verdadeiro teste de autonomia.
Se o deploy do seu serviço exige que outro esteja pronto, o que você tem é acoplamento temporal — e isso é veneno para sistemas distribuídos.
E por que isso acontece?
Porque autonomia não nasce da separação de código.
Ela nasce de limites bem definidos de domínio, ownership real e contratos estáveis.
📌 Eric Evans, pai do Domain-Driven Design, nos dá a pista aqui:
“Design eficaz vem da descoberta de limites naturais de contexto. Se você ignora isso, fragmenta o sistema sem critério.” — Eric Evans, DDD Blue Book
Separar o código sem separar as responsabilidades não traz autonomia — traz mais pontos de falha.
Como corrigir esse caminho?
Reveja os limites de domínio.
Se dois serviços precisam do mesmo banco, talvez sejam o mesmo serviço.Evite dependência em tempo de execução.
Prefira eventos assíncronos, filas, pub/sub — e cuidado com a falsa sensação de segurança.
📌 Sam Newman recomenda o uso de comunicação assíncrona sempre que possível para reduzir o acoplamento temporal.
“Chamadas síncronas introduzem acoplamento temporal — você depende da disponibilidade de outro serviço. Sistemas baseados em eventos evitam isso.” — Sam Newman
Documente e versione contratos com clareza.
O consumidor do seu serviço não pode ser seu refém.Crie observabilidade isolada por serviço.
Se um serviço falha, o resto não deveria cair junto. E você precisa ver isso rapidamente.
📌 Charity Majors complementa:
“Se você não consegue observar o comportamento do serviço de forma isolada, você não tem microserviços. Tem uma névoa distribuída.” — Charity Majors
Teste os limites de autonomia.
Desligue serviços. Veja o que acontece.
Microserviços reais sobrevivem ao isolamento. Os outros... sobrevivem na reunião de incidentes.
Você quer arquitetura distribuída...
Ou só quer espalhar seu problema em serviços diferentes e torcer pra ninguém perceber?
Porque microserviços custam caro.
E só fazem sentido quando o ganho de autonomia justifica a complexidade.
📌 Martin Fowler, novamente:
“Microsserviços não são um almoço grátis. Eles exigem uma maturidade de engenharia significativa para funcionar bem.” — Martin Fowler
Senão, um monolito bem feito vai te dar menos dor de cabeça, menos latência e mais paz.
Arquitetura Orientada a Eventos... ou ao Caos?
"Emitir evento é fácil. Difícil é entender o que ele realmente significa."
Antes de falar de observabilidade, a gente precisa tirar um elefante da sala:
A febre da arquitetura orientada a eventos mesmo em empresas sem maturidade técnica ou organizacional pra lidar com ela.
Porque sim, eventos são lindos no papel:
Reduzem o acoplamento direto entre serviços,
Permitem comunicação assíncrona,
Ajudam a escalar de forma mais fluida e desacoplada.
Mas só se você souber o que está fazendo.
Eventos precisam carregar significado. Não só dados.
Emitir evento não é só "jogar JSON numa fila".
Eventos são comunicação entre contextos — e comunicação exige clareza, intenção e semântica.
Não basta publicar:
{ "userId": "123", "status": "active" }
É preciso responder:
O que aconteceu?
O que esse evento representa no modelo de negócio?
Qual o significado de cada campo?
Que decisão motivou esse evento?
Que ações esse evento pode disparar?
Eventos que não carregam contexto são como bilhetes rasgados.
Não servem pra tomar decisões. Só pra gerar confusão.
📌 Martin Fowler alerta:
“O nome do evento deve refletir um fato de negócio. Não uma ação técnica.”
Exemplo:"OrderShipped"
é melhor do que"SetStatusToShipped"
.
Acrescente contexto: use campos como reason
Uma prática poderosa (e muitas vezes ignorada) é adicionar ao evento um campo como:
"reason": "MANUAL_ACCOUNT_REVIEW_APPROVED"
Ou seja:
Além de saber o que aconteceu, você informa por que aconteceu, de forma explícita, controlada e documentada.
Isso ajuda a:
Evitar múltiplas interpretações do mesmo evento.
Facilitar testes e rastreamento.
Criar filtros inteligentes em sistemas downstream.
Aumentar a confiança do time de negócio no sistema.
📌 Mas atenção: esse reason
não é texto livre.
Ele deve seguir uma nomenclatura bem definida, versionada, e vinculada ao domínio.
Exemplos:
"PAYMENT_FAILED_INSUFFICIENT_FUNDS"
"ORDER_CANCELED_OUT_OF_STOCK"
"USER_ACTIVATED_MANUAL_REVIEW"
Quanto mais clara e estável for a estrutura desse campo, mais previsível será o comportamento do sistema.
E mais importante, isso aproxima a modelagem técnica da linguagem do negócio.
Sem alinhamento com o negócio, os eventos viram ruído
Eventos precisam refletir fatos reais no domínio da empresa.
Mas o que mais se vê por aí é:
Dev criando eventos sem conversar com analistas, PO ou produto.
Nomes vagos como
DataUpdated
,ClientSynced
,FlagTriggered
.Eventos que significam coisas diferentes pra cada squad.
Casos em que um evento gera comportamento crítico em outro serviço... mas ninguém tem certeza disso.
📌 Exemplo:
Um evento UserActivated
pode parecer simples.
Mas em outro serviço, ele inicia cobrança, envia e-mail, habilita features premium.
Se um evento tem impacto financeiro, regulatório ou jurídico, ele não pode nascer da cabeça de um dev numa sexta-feira.
📌 Sam Newman alerta sobre isso:
“O design de eventos deve envolver perspectivas técnicas e comerciais. Caso contrário, você cria artefatos técnicos que ninguém entende ou confia.”
💥 Eventos são contratos. E contratos precisam ser claros.
Cada evento emitido é um contrato entre quem publica e quem consome.
E como todo contrato, ele precisa de:
Clareza,
Estabilidade,
Evolução versionada,
Documentação.
Sem isso, você tem um sistema onde:
Alterar um campo quebra serviços silenciosamente,
Consumidores interpretam o mesmo evento de formas diferentes,
E você descobre consumidores que ninguém sabia que existiam só quando o incidente acontece.
📌 Charity Majors novamente:
"Não se pode depurar o que não se vê, e não se pode confiar no que não se entende. Isso é especialmente verdadeiro para eventos."
O acoplamento disfarçado
Eventos vendem a promessa de desacoplamento.
Mas quando são mal projetados, mal gerenciados e sem semântica, você cria um acoplamento invisível:
O produtor nem sabe quem consome.
O consumidor depende de ordem de eventos, delays, ou campos mágicos.
O time não tem visibilidade nem controle sobre o que está sendo orquestrado.
Ou seja:
Você não tem um sistema orientado a eventos.
Você tem uma teia de aranha distribuída — e ela cresce sem ninguém ver.
E o tal do Event Sourcing?
A gente não vai mergulhar nesse tema agora, mas vale um alerta:
Event Sourcing ≠ Arquitetura Orientada a Eventos
Arquitetura orientada a eventos é sobre comunicação entre serviços.
Event Sourcing é sobre armazenar o estado do sistema como uma sequência de eventos imutáveis.
E embora use eventos, Event Sourcing exige um nível ainda mais alto de maturidade:
Clareza semântica dos eventos é obrigatória (não opcional).
O modelo de leitura (read model) depende de projeções baseadas nesses eventos.
Eventos nunca podem ser alterados — e qualquer erro vira legado eterno.
📌 Greg Young, criador do conceito:
“Se você errar no design do seu evento, ele não será apenas ruim — será irreversível.”
Por isso, não comece usando Event Sourcing achando que está "só organizando melhor seus eventos".
É outra arquitetura. Outro nível de comprometimento. Outro tipo de responsabilidade.
Vou tentar resumir tudo:
Eventos são poderosos, mas só nas mãos certas.
Se você quer usar eventos:
Trate-os como contratos.
Dê nome com semântica de negócio.
Versione. Documente. Monitore.
Alinhe com o negócio antes de alinhar com o Kafka.
E entenda que mais eventos ≠ mais arquitetura.
Observabilidade é Sempre um ‘Depois a Gente Faz’ 🔍
“Se a arquitetura não te conta o que está sentindo, ela vai te dar um susto.”
Você já ouviu essa:
"O sistema tá no ar."
Mas a pergunta real é:
"Tá tudo bem com ele?"
Porque estar no ar não significa estar saudável.
😶🌫️ Voando às cegas
Sistemas distribuídos são como aviões em pleno voo:
Vários motores, controles espalhados, sensores em tudo quanto é canto…
Mas em muitos projetos, a gente monta o avião inteiro e esquece de instalar o painel.
Não tem logs estruturados, só
console.log
perdido.Não tem tracing entre serviços, então cada request vira um labirinto.
As métricas são genéricas — tipo “CPU usage” — e não dizem nada sobre o negócio.
E as dashboards… bom, tem um Grafana que ninguém olha até o sistema cair.
📌 Charity Majors, uma das maiores referências sobre observabilidade, é categórica:
"O monitoramento avisa quando algo está errado. A observabilidade informa o porquê."
O problema começa no design
Observabilidade não é um acessório que você pluga no final.
Ela precisa ser embutida no design da arquitetura desde o início.
Cada serviço deve nascer com logging estruturado, com correlação entre requisições.
Cada fluxo de negócio precisa ter eventos de rastreamento que indiquem o que aconteceu.
Cada time deve saber como medir a saúde do que construiu e não só se tá respondendo 200.
📌 Sam Newman reforça isso:
“Se você está construindo microsserviços, a observabilidade não é opcional. É fundamental.”
O que falta (quase sempre):
Trace ID passando entre serviços, não basta logar, tem que ligar os pontos.
Campos de negócio nos logs, como
"orderId"
,"customerId"
— não só"timestamp"
e"level"
.Alertas com contexto, que dizem o que quebrou, onde, e por quê, não só “erro 500”.
Visibilidade sobre consumidores de eventos — quem processou o quê, quando e com sucesso ou falha?
Dashboard que responde perguntas reais, tipo:
Quantos pedidos falharam por timeout externo?
Qual é o tempo médio entre “pedido criado” e “pedido faturado”?
Qual serviço é o maior causador de erros downstream?
Sem isso, você está operando um sistema complexo no escuro.
E o problema de sistemas no escuro é que eles explodem sem aviso.
"Mas nunca deu problema..."
Claro. Ainda.
Mas observabilidade não serve só pra achar bug.
Ela serve pra:
Prever colapsos antes que eles aconteçam.
Dar autonomia pra cada time cuidar do que constrói.
Reduzir MTTR (tempo de recuperação).
Eliminar achismo na análise de causa raiz.
Quer distribuir responsabilidade? Dê visibilidade.
Arquitetura distribuída só funciona se o conhecimento também for distribuído.
E isso só acontece quando cada pessoa consegue:
Ver o estado real do sistema,
Rastrear o caminho de uma requisição,
Entender por que algo aconteceu,
Agir com base em dados — não em desespero.
📌 Como resume Charity Majors:
“Se você precisa perguntar a alguém o que está acontecendo com o sistema… você não tem observabilidade.”
🛠 Como começar agora
Adote tracing distribuído (OpenTelemetry, AWS X-Ray, Datadog, etc.)
Estruture seus logs (JSON, correlação, IDs de negócio)
Inclua KPIs de negócio como parte das métricas — não só saúde técnica
Monitore eventos como cidadãos de primeira classe
Treine seu time para tratar observabilidade como responsabilidade de engenharia — não só da SRE
Resumindo um pouco:
Sistemas distribuídos sem observabilidade não são sofisticados. São perigosos.
E não importa se o sistema está no ar, se ninguém consegue ver o que está acontecendo, você não está operando um sistema. Está torcendo.
Time Despreparado Para Operar o Que Foi Desenhado 🧯
“Quem desenha não sobe o sistema. E quem sobe não entendeu o desenho.”
A arquitetura pode ser linda no Figma. Os fluxos podem estar claros no draw.io.
Mas nenhuma dessas coisas prepara o sistema pra realidade da produção se o time que vai operar essa arquitetura foi deixado de fora da conversa.
E aqui vai uma verdade desconfortável:
👉🏻 Em muitos times, o pessoal que escreve o código e assina a arquitetura nunca vê o sistema de pé, em ambiente real.
👉🏻 Enquanto isso, quem monitora, faz deploy, apaga incêndio ou precisa restaurar em caso de falha... não tem ideia por que aquela decisão arquitetural foi tomada.
O resultado? Você tem um abismo.
E entre esse abismo está a sua produção, equilibrada na ponta de um deploy.
Do “tá funcionando na minha máquina” ao “é só rodar o Helm chart”
Hoje o “funciona aqui” não vive mais no notebook do dev.
Ele vive num repositório com scripts Kubernetes e um Helm chart que, supostamente, deveria resolver tudo com um helm install
.
Mas a realidade chega rápido:
A role do serviço não foi provisionada.
A variável
APP_ENV=production
só existe na máquina de quem fez o deploy da última vez.E ninguém avisou que esse serviço depende de outro que ainda nem foi atualizado.
Você sobe o sistema, mas ele vem faltando peças, como um Lego mal montado.
Ou pior: ele sobe e parece estar funcionando até alguém clicar em algo que ninguém testou. Porque ninguém sabia como deveria funcionar de verdade.
Quando o conhecimento é tribal, o risco é institucional
Sistemas complexos, operados com base em memória e tradição oral, viram armadilhas corporativas.
Quem realmente entende a infraestrutura?
Aquele dev sênior que configurou tudo há 2 anos?
O analista de SRE que guarda um script mágico no Gist pessoal?
Um ex-funcionário que deixou um bash rodando dentro do Jenkins?
📌 Esse tipo de sistema só se mantém de pé enquanto ninguém sai de férias.
Ele não é resiliente.
Ele é dependente de heróis.
“Sistemas resilientes não pedem por heróis na operação. Se você precisa do especialista, algo está errado na arquitetura.”
A arquitetura só vai até onde o time entende
Você pode ter desenhado um sistema distribuído com:
Tracing,
Cache,
Circuit breaker,
Auto-healing,
Service mesh...3
Mas se ninguém sabe:
Subir do zero,
Corrigir um erro de configuração,
Entender a sequência de fallback,
Identificar um comportamento anômalo,
Saber quando e por que fazer rollback...
Então sua arquitetura é só um PowerPoint sofisticado. E sistemas não quebram só por falhas técnicas. Eles quebram por falta de compreensão operacional.
O que precisamos melhorar no dia a dia
1. Arquitetura feita com o time, não apenas para o time
Antes de decidir por Kafka, Kustomize, Prometheus, Redis, Redis Cluster e mais 3 serviços event-driven, pare e pergunte:
Quem vai manter isso vivo na madrugada?
As ferramentas escolhidas já existem no ecossistema do time?
O time tem maturidade pra operar essa stack?
As ferramentas escolhidas já existem no ecossistema do time?
Arquitetura de verdade inclui quem opera.
É desenhada com o chão da fábrica em mente.
2. Documentação viva, mínima, mas presente
Não estamos pedindo uma bíblia.
Mas um README.md
decente pode evitar horas de frustração:
Como subir?
Como depurar?
Como restaurar dados?
Como simular um cenário de erro?
Além disso:
Scripts versionados no repositório.
Nada de comandos mágicos na cabeça de alguém.
Arquivos
adr/
com as decisões arquiteturais justificadas: por que usamos isso, quais foram os trade-offs, o que foi descartado.
3. Reuniões antes do incidente
Não é depois que o sistema caiu que se pergunta:
O que é normal aqui?
Esse alerta é real ou ruído?
Isso é só uma lentidão ou tem impacto financeiro?
Qual parte do sistema pode ser desligada?
O que dá rollback? O que pode ser ignorado?
Essas conversas precisam acontecer enquanto tudo ainda está em paz.
Porque em guerra, todo mundo só corre.
4. Testes de operação: simule o caos com frequência
Tira uma variável de ambiente e sobe o sistema.
Força o banco a ficar indisponível por 5 segundos.
Simula um pico de requisições no serviço mais frágil.
Derruba um serviço e observa se os alertas realmente disparam.
Esses testes revelam o que o diagrama nunca mostrou.
5. Compartilhar conhecimento por padrão. Documentar como cultura.
Faça sessões de pair entre devs e operações.
Crie pequenos workshops internos de “como funciona nosso deploy”.
Escreva playbooks simples. Curto, direto, útil.
Porque quanto mais o conhecimento circula, menos o sistema depende de super-heróis.
E mais ele depende de colaboração, cultura e clareza.
Para finalizar…
Você não tem uma arquitetura operacional até que seu time consiga:
Subir com confiança,
Depurar com autonomia,
Corrigir com agilidade,
E evoluir com segurança.
Senão, o que você tem é uma promessa de arquitetura.
A Arquitetura Que Sobrevive
Se você leu tudo até aqui, parabéns.
Você não só quer escrever código.
Você quer entender o que está por trás do caos e construir algo que resista a ele.
Porque a verdade é dura — mas libertadora:
🚫 Arquitetura bonita não sustenta sistema.
🚫 Diagramas complexos não protegem de incidentes.
🚫 Naming chique não evita rollback.
No final do dia, o que importa é:
✔️ Se o sistema aguenta falhar com dignidade,
✔️ Se o time sabe como operar sem depender de heróis,
✔️ Se os eventos têm significado e não são só JSONs jogados em filas,
✔️ Se a observabilidade está presente antes da crise,
✔️ Se a autonomia prometida não virou um monolito distribuído de expectativas frustradas.
Engenharia de software real não é sobre parecer moderno — é sobre lidar com a realidade.
É saber que sistemas quebram. Pessoas erram. Ambientes mudam.
E que o papel da arquitetura não é evitar o caos —
É garantir que a gente saiba navegar por ele.
Como disse Charity Majors:
“Se você precisa de um especialista pra saber o que está acontecendo, você não tem sistema. Você tem um feitiço.”
Então a pergunta que fica pra você e seu time é simples:
O que você está construindo?
Um castelo no PowerPoint?
Ou uma fundação que, mesmo imperfeita, consegue resistir, reagir e evoluir?
Porque no fim, arquitetura boa não é a que impressiona no workshop —
É a que funciona no caos.
E mais do que isso:
É a que o time inteiro consegue operar, entender, confiar e melhorar.
Essa é a arquitetura que sobrevive.
https://www.pagerduty.com/resources/engineering/learn/what-is-chaos-testing/
Um cron job é uma tarefa programada que roda automaticamente em um intervalo de tempo definido, como a cada minuto, hora, dia ou semana.
Ele é muito usado para rotinas como:
Enviar e-mails automáticos,
Sincronizar dados entre sistemas,
Limpar arquivos temporários,
Rodar scripts de manutenção.
No contexto de microserviços, o cron job pode parecer inofensivo, mas quando mal documentado ou dependente de serviços externos, ele se torna uma bomba-relógio escondida, difícil de debugar, monitorar e até de lembrar que existe.
O que é Service Mesh?
Service Mesh é uma camada de infraestrutura que cuida da comunicação entre serviços dentro de um sistema distribuído (como microservices), sem que os próprios serviços precisem saber disso.
Ele gerencia automaticamente:
🔒 Segurança (ex: criptografia mTLS entre serviços)
📊 Observabilidade (logs, métricas e tracing)
🔁 Retries, timeouts e circuit breakers
🧭 Roteamento inteligente de tráfego
Tudo isso acontece fora do código da aplicação, geralmente com sidecars (como o Envoy) instalados junto a cada serviço.
Pense como um “Waze” para seus serviços: ele cuida do caminho, do tráfego e da segurança, enquanto os serviços só precisam se preocupar com o destino final.