[{"data":1,"prerenderedAt":2853},["ShallowReactive",2],{"article-\u002Fsistemas\u002Farquitetura-de-microservicos-escalaveis":3},{"id":4,"title":5,"author":6,"body":7,"category":2836,"date":2837,"description":2838,"extension":2839,"keywords":2840,"meta":2847,"navigation":772,"path":2848,"seo":2849,"slug":2850,"stem":2851,"updated":2837,"__hash__":2852},"content\u002Fsistemas\u002Farquitetura-de-microservicos-escalaveis.md","Arquitetura de microserviços escaláveis: guia 2026","Inicialize Tec",{"type":8,"value":9,"toc":2789},"minimark",[10,15,80,84,96,113,116,154,159,258,262,269,273,305,309,329,341,349,353,357,368,375,416,426,432,436,447,454,484,490,494,505,512,532,536,547,557,565,568,582,588,596,600,604,615,642,650,654,665,686,821,825,836,842,862,978,986,990,1000,1007,1015,1019,1101,1117,1129,1133,1136,1160,1164,1168,1186,1189,1511,1519,1523,1591,1599,1607,1611,1777,1784,1788,1793,1804,1807,1811,1980,1986,1994,1998,2018,2023,2060,2064,2075,2085,2091,2099,2103,2174,2181,2185,2241,2269,2273,2277,2283,2289,2295,2300,2306,2310,2315,2319,2354,2358,2390,2394,2399,2403,2409,2413,2419,2423,2428,2433,2520,2524,2529,2533,2568,2572,2649,2653,2657,2671,2681,2685,2688,2708,2714,2740,2745,2765,2771,2774,2785],[11,12,14],"h2",{"id":13},"índice","Índice",[16,17,18,26,32,38,44,50,56,62,68,74],"ol",{},[19,20,21],"li",{},[22,23,25],"a",{"href":24},"#o-que-sao","O que são microserviços?",[19,27,28],{},[22,29,31],{"href":30},"#quando","Quando (não) usar microserviços",[19,33,34],{},[22,35,37],{"href":36},"#padroes","Padrões arquiteturais",[19,39,40],{},[22,41,43],{"href":42},"#comunicacao","Comunicação entre serviços",[19,45,46],{},[22,47,49],{"href":48},"#dados","Dados em microserviços",[19,51,52],{},[22,53,55],{"href":54},"#deploy","Deploy e orquestração",[19,57,58],{},[22,59,61],{"href":60},"#observabilidade","Observabilidade",[19,63,64],{},[22,65,67],{"href":66},"#numeros","Escala real: números",[19,69,70],{},[22,71,73],{"href":72},"#erros","Erros comuns",[19,75,76],{},[22,77,79],{"href":78},"#caso-real","Caso real: fintech que escalou de 5K a 2M usuários",[11,81,83],{"id":82},"o-que-são-microserviços-o-que-sao","O que são microserviços? {#o-que-sao}",[85,86,87,91,92,95],"p",{},[88,89,90],"strong",{},"Microserviços"," são uma forma de organizar um sistema de software em que,\nem vez de construir uma única aplicação grande (chamada ",[88,93,94],{},"monolito","), você\ndivide em vários serviços pequenos e independentes, cada um responsável por\numa área específica do negócio.",[97,98,99,108],"blockquote",{},[85,100,101,104,105,107],{},[88,102,103],{},"Analogia",": Imagine uma cozinha de restaurante. Um ",[88,106,94],{}," é como\num cozinheiro que faz tudo: prepara a entrada, o prato principal, a sobremesa,\nlava a louça, atende o garçom. Se ele fica doente, o restaurante inteiro para.",[85,109,110,112],{},[88,111,90],{}," são como uma cozinha com estações separadas: uma para\nentradas, uma para grelhados, uma para sobremesas, uma para lavar louça.\nCada estação trabalha independentemente. Se a estação de sobremesas quebra,\no restaurante ainda serve entradas e pratos principais.",[85,114,115],{},"Cada microserviço:",[117,118,119,126,133,140,147],"ul",{},[19,120,121,122,125],{},"Tem seu próprio ",[88,123,124],{},"banco de dados"," (não compartilha com outros)",[19,127,128,129,132],{},"Pode ser ",[88,130,131],{},"deployado"," (colocado em produção) independentemente",[19,134,135,136,139],{},"Pode ser escrito em ",[88,137,138],{},"linguagens diferentes"," (um em Python, outro em Go)",[19,141,142,143,146],{},"Pode ",[88,144,145],{},"escalar"," (crescer para atender mais usuários) independentemente",[19,148,149,150,153],{},"Comunica-se com outros serviços via ",[88,151,152],{},"rede"," (API, eventos)",[155,156,158],"h3",{"id":157},"monolito-vs-microserviços-visão-geral","Monolito vs Microserviços — visão geral",[160,161,162,177],"table",{},[163,164,165],"thead",{},[166,167,168,172,175],"tr",{},[169,170,171],"th",{},"Aspecto",[169,173,174],{},"Monolito",[169,176,90],{},[178,179,180,192,203,214,225,236,247],"tbody",{},[166,181,182,186,189],{},[183,184,185],"td",{},"Estrutura",[183,187,188],{},"Uma aplicação, um código",[183,190,191],{},"Vários serviços independentes",[166,193,194,197,200],{},[183,195,196],{},"Banco de dados",[183,198,199],{},"Um banco compartilhado",[183,201,202],{},"Cada serviço tem o seu",[166,204,205,208,211],{},[183,206,207],{},"Deploy",[183,209,210],{},"Todo o sistema de uma vez",[183,212,213],{},"Cada serviço separadamente",[166,215,216,219,222],{},[183,217,218],{},"Escala",[183,220,221],{},"Tudo escala junto",[183,223,224],{},"Cada serviço escala na medida",[166,226,227,230,233],{},[183,228,229],{},"Complexidade",[183,231,232],{},"Baixa no início, alta depois",[183,234,235],{},"Alta desde o início",[166,237,238,241,244],{},[183,239,240],{},"Time",[183,242,243],{},"Funciona com time pequeno",[183,245,246],{},"Precisa de times maiores",[166,248,249,252,255],{},[183,250,251],{},"Manutenção",[183,253,254],{},"Mudanças afetam tudo",[183,256,257],{},"Mudanças isoladas por serviço",[11,259,261],{"id":260},"quando-não-usar-microserviços-quando","Quando (não) usar microserviços {#quando}",[85,263,264,265,268],{},"Microserviços ",[88,266,267],{},"não são bala de prata"," (não resolvem todos os problemas).\nNa verdade, para muitos projetos, um monolito é a escolha certa.",[155,270,272],{"id":271},"use-microserviços-quando","Use microserviços quando:",[117,274,275,281,287,293,299],{},[19,276,277,280],{},[88,278,279],{},"Time > 8 pessoas",": a complexidade operacional só se justifica com um\ntime grande o suficiente para manter múltiplos serviços",[19,282,283,286],{},[88,284,285],{},"Domínios distintos",": e-commerce, pagamentos e logística têm ciclos de\ndesenvolvimento e necessidades diferentes. Faz sentido separá-los.",[19,288,289,292],{},[88,290,291],{},"Escala diferenciada",": o catálogo de produtos recebe 100x mais tráfego\nque o checkout. Separando, você escala só o catálogo.",[19,294,295,298],{},[88,296,297],{},"Deploy independente",": times precisam liberar atualizações sem coordenar\ncom outros times",[19,300,301,304],{},[88,302,303],{},"Requisitos técnicos diferentes",": o serviço de busca precisa de\nElasticsearch, o de pagamentos precisa de PostgreSQL transacional",[155,306,308],{"id":307},"não-use-microserviços-quando","NÃO use microserviços quando:",[117,310,311,317,323],{},[19,312,313,316],{},[88,314,315],{},"Time \u003C 5 pessoas",": monolito modular (um código organizado em módulos\nbem separados) é mais produtivo e simples de manter",[19,318,319,322],{},[88,320,321],{},"MVP \u002F fase inicial",": valide o produto antes de otimizar a arquitetura.\n\"Primeiro faça funcionar, depois faça rápido, depois faça bonito.\"",[19,324,325,328],{},[88,326,327],{},"\"Porque o Netflix usa\"",": você não é o Netflix (ainda). O Netflix tem\nmilhares de engenheiros e bilhões de requisições. Sua startup com 500\nusuários não precisa da mesma arquitetura.",[97,330,331],{},[85,332,333,336,337,340],{},[88,334,335],{},"Regra de ouro",": Comece com ",[88,338,339],{},"monolito modular"," (um código só, mas\norganizado em módulos bem separados). Extraia microserviços apenas quando\num domínio específico tiver requisitos de escala, deploy ou time que\njustifiquem a separação.",[97,342,343],{},[85,344,345,348],{},[88,346,347],{},"Erro comum",": O CTO lê um artigo sobre \"Netflix migrou para\nmicroserviços\" e decide migrar a startup com 3 desenvolvedores e 200\nusuários. Resultado: 6 meses migrando, nenhuma feature nova lançada,\ne o sistema ficou mais lento e mais difícil de manter.",[11,350,352],{"id":351},"padrões-arquiteturais-padroes","Padrões arquiteturais {#padroes}",[155,354,356],{"id":355},"api-gateway","API Gateway",[97,358,359],{},[85,360,361,363,364,367],{},[88,362,103],{},": O API Gateway é como a ",[88,365,366],{},"recepção de um prédio comercial",".\nTodos os visitantes entram pela recepção. A recepcionista verifica a\nidentidade (autenticação), diz para qual sala ir (roteamento), limita\nquantas pessoas entram por hora (rate limiting) e pode dar informações\nde múltiplos andares em uma única visita (agregação).",[85,369,370,371,374],{},"O API Gateway é o ",[88,372,373],{},"ponto único de entrada"," para todos os clientes. Ele é\nresponsável por:",[117,376,377,392,398,404,410],{},[19,378,379,382,383,387,388,391],{},[88,380,381],{},"Roteamento",": cada request vai para o serviço certo\n(",[384,385,386],"code",{},"GET \u002Fpedidos"," → serviço de pedidos, ",[384,389,390],{},"GET \u002Fprodutos"," → serviço de catálogo)",[19,393,394,397],{},[88,395,396],{},"Autenticação\u002FAutorização",": verifica quem é o usuário e o que pode fazer",[19,399,400,403],{},[88,401,402],{},"Rate limiting",": limita quantas requisições um cliente pode fazer por minuto",[19,405,406,409],{},[88,407,408],{},"Transformação de request\u002Fresponse",": converte formatos se necessário",[19,411,412,415],{},[88,413,414],{},"Agregação de múltiplos serviços",": combina respostas de vários serviços\nem uma única resposta para o cliente",[417,418,423],"pre",{"className":419,"code":421,"language":422},[420],"language-text","[Cliente] → [API Gateway] → [Serviço de Pedidos]\n                          → [Serviço de Catálogo]\n                          → [Serviço de Pagamentos]\n","text",[384,424,421],{"__ignoreMap":425},"",[85,427,428,431],{},[88,429,430],{},"Ferramentas populares",": Kong, AWS API Gateway, Traefik, Envoy",[155,433,435],{"id":434},"service-mesh","Service Mesh",[97,437,438],{},[85,439,440,442,443,446],{},[88,441,103],{},": Service Mesh é como um ",[88,444,445],{},"sistema de rádio interno"," do\nprédio. Cada andar (serviço) se comunica com outros andares pelo rádio,\nsem precisar saber o número da sala. O sistema de rádio garante que a\ncomunicação é segura (criptografada), rastreável (gravada) e resiliente\n(se uma sala não responde, tenta de novo automaticamente).",[85,448,449,450,453],{},"Service Mesh lida com a comunicação ",[88,451,452],{},"service-to-service"," (entre serviços,\nnão entre cliente e serviço):",[117,455,456,462,468,474],{},[19,457,458,461],{},[88,459,460],{},"mTLS"," (mutual TLS): criptografia em trânsito entre serviços",[19,463,464,467],{},[88,465,466],{},"Retry\u002Fcircuit breaker",": se um serviço falha, tenta de novo; se continua\nfalhando, \"desarma o disjuntor\" e para de tentar (explico abaixo)",[19,469,470,473],{},[88,471,472],{},"Distributed tracing",": rastreia uma requisição através de múltiplos serviços",[19,475,476,479,480,483],{},[88,477,478],{},"Traffic splitting",": divide tráfego entre versões (ex: 95% v1, 5% v2\npara testar nova versão — chamado ",[88,481,482],{},"canary deploy",")",[85,485,486,489],{},[88,487,488],{},"Ferramentas",": Istio, Linkerd, Consul Connect",[155,491,493],{"id":492},"backend-for-frontend-bff","Backend for Frontend (BFF)",[97,495,496],{},[85,497,498,500,501,504],{},[88,499,103],{},": Em vez de uma recepção única para todos (API Gateway padrão),\no BFF é como ter ",[88,502,503],{},"recepções especializadas",": uma para visitantes, uma\npara entregadores, uma para fornecedores. Cada uma atende as necessidades\nespecíficas de cada tipo de visitante.",[85,506,507,508,511],{},"Um ",[88,509,510],{},"BFF"," (Backend for Frontend) é um gateway especializado por tipo de\ncliente:",[117,513,514,520,526],{},[19,515,516,519],{},[88,517,518],{},"Web BFF",": agrega dados para o dashboard completo do navegador",[19,521,522,525],{},[88,523,524],{},"Mobile BFF",": responde só o essencial (menos dados = menos consumo de\nbateria e dados móveis)",[19,527,528,531],{},[88,529,530],{},"Partner BFF",": expõe apenas endpoints públicos para parceiros\u002Fintegradores",[155,533,535],{"id":534},"saga-pattern","Saga Pattern",[97,537,538],{},[85,539,540,542,543,546],{},[88,541,103],{},": Saga é como uma ",[88,544,545],{},"corrida de revezamento",". Em vez de uma\núnica transação que faz tudo (o que seria impossível entre serviços\ndiferentes), cada serviço faz sua parte e passa o bastão para o próximo.\nSe um corredor tropeça, os anteriores precisam \"desfazer\" o que fizeram\n(compensação).",[85,548,549,552,553,556],{},[88,550,551],{},"Saga"," é o padrão para ",[88,554,555],{},"transações distribuídas"," — quando uma operação\nprecisa mudar dados em múltiplos serviços e não há como fazer tudo em uma\ntransação única (ACID).",[97,558,559],{},[85,560,561,564],{},[88,562,563],{},"Por que não transação ACID?",": ACID (Atomicidade, Consistência, Isolamento,\nDurabilidade) garante que tudo acontece ou nada acontece. Mas quando os dados\nestão em bancos diferentes (cada microserviço tem o seu), não dá para fazer\numa transação que englobe todos. Saga resolve isso com compensação.",[85,566,567],{},"Dois estilos de Saga:",[117,569,570,576],{},[19,571,572,575],{},[88,573,574],{},"Choreography"," (coreografia): cada serviço publica um evento, o próximo\nserviço reage automaticamente. Sem orquestrador central.",[19,577,578,581],{},[88,579,580],{},"Orchestration"," (orquestração): um orquestrador coordena a sequência,\nchamando cada serviço na ordem certa.",[417,583,586],{"className":584,"code":585,"language":422},[420],"[Pedido criado] → [Estoque reservado] → [Pagamento processado] → [Pedido confirmado]\n      ↓ falha no pagamento\n[Estoque liberado] ← (compensação: desfaz a reserva)\n",[384,587,585],{"__ignoreMap":425},[97,589,590],{},[85,591,592,595],{},[88,593,594],{},"Analogia da compensação",": Você comprou um produto online. O sistema\nreservou o estoque, processou o pagamento, mas o pagamento foi recusado.\nA Saga desfaz: libera o estoque que estava reservado. É como devolver um\nitem à prateleira quando o cartão é recusado no caixa.",[11,597,599],{"id":598},"comunicação-entre-serviços-comunicacao","Comunicação entre serviços {#comunicacao}",[155,601,603],{"id":602},"síncrona-restgrpc","Síncrona (REST\u002FgRPC)",[97,605,606],{},[85,607,608,610,611,614],{},[88,609,103],{},": Comunicação síncrona é como uma ",[88,612,613],{},"ligação telefônica",". Você\nliga, espera a pessoa atender, pergunta, espera a resposta, e só depois\ndesliga. Se a pessoa não atende, você fica esperando.",[117,616,617,623,633],{},[19,618,619,622],{},[88,620,621],{},"Use para",": consultas que precisam de resposta imediata (ex: \"este produto\nestá em estoque?\")",[19,624,625,628,629,632],{},[88,626,627],{},"Problema",": ",[88,630,631],{},"acoplamento temporal"," — se o serviço B cai, o serviço A\ntambém \"cai\" (fica esperando resposta que nunca vem)",[19,634,635,628,638,641],{},[88,636,637],{},"Mitigação",[88,639,640],{},"circuit breaker"," (disjuntor) — se B falha N vezes seguidas,\nA para de tentar e responde com um fallback (resposta degradada) em vez de\nficar esperando",[97,643,644],{},[85,645,646,649],{},[88,647,648],{},"O que é Circuit Breaker?",": Como o disjuntor da sua casa. Se há um\ncurto-circuito (serviço B falhando), o disjuntor \"desarma\" e corta a energia\n(para de chamar B). Após um tempo, tenta \"religar\" (half-open) para ver se\nB voltou. Se sim, volta ao normal. Se não, desarma de novo. Ferramentas:\nResilience4j (Java), Polly (.NET), opossum (Node.js).",[155,651,653],{"id":652},"assíncrona-eventosmensagens","Assíncrona (Eventos\u002FMensagens)",[97,655,656],{},[85,657,658,660,661,664],{},[88,659,103],{},": Comunicação assíncrona é como ",[88,662,663],{},"mandar um e-mail",". Você\nescreve, envia e continua sua vida. Não espera a pessoa responder para\ncontinuar trabalhando. Quando ela responder, você lê.",[117,666,667,672,677],{},[19,668,669,671],{},[88,670,621],{},": comandos que podem ser processados depois (ex: \"envie e-mail\nde confirmação\", \"recalcule o score do cliente\")",[19,673,674,676],{},[88,675,488],{},": Kafka, RabbitMQ, NATS, Amazon SQS",[19,678,679,628,682,685],{},[88,680,681],{},"Vantagem",[88,683,684],{},"desacoplamento temporal"," — o produtor não depende do\nconsumidor estar online",[417,687,691],{"className":688,"code":689,"language":690,"meta":425,"style":425},"language-python shiki shiki-themes github-light github-dark","# Padrão: evento publicado, múltiplos serviços consomem independentemente\norder_created = {\n    \"event_id\": \"uuid-123\",                    # ID único do evento\n    \"event_type\": \"order.created\",             # tipo do evento\n    \"data\": {\n        \"order_id\": 456,\n        \"customer_id\": 789,\n        \"total\": 199.90,\n        \"items\": [{\"product_id\": 1, \"qty\": 2}]\n    },\n    \"timestamp\": \"2026-08-26T10:00:00Z\"\n}\n\n# Publica no Kafka\u002FRabbitMQ — não espera ninguém processar\nproducer.send(\"order-events\", order_created)\n\n# Múltiplos serviços consomem independentemente:\n# - Serviço de estoque consome → reserva os itens\n# - Serviço de notificação consome → envia e-mail de confirmação\n# - Serviço de analytics consome → atualiza dashboard de vendas\n# Cada um faz sua parte sem depender dos outros\n","python",[384,692,693,701,707,713,719,725,731,737,743,749,755,761,767,774,780,786,791,797,803,809,815],{"__ignoreMap":425},[694,695,698],"span",{"class":696,"line":697},"line",1,[694,699,700],{},"# Padrão: evento publicado, múltiplos serviços consomem independentemente\n",[694,702,704],{"class":696,"line":703},2,[694,705,706],{},"order_created = {\n",[694,708,710],{"class":696,"line":709},3,[694,711,712],{},"    \"event_id\": \"uuid-123\",                    # ID único do evento\n",[694,714,716],{"class":696,"line":715},4,[694,717,718],{},"    \"event_type\": \"order.created\",             # tipo do evento\n",[694,720,722],{"class":696,"line":721},5,[694,723,724],{},"    \"data\": {\n",[694,726,728],{"class":696,"line":727},6,[694,729,730],{},"        \"order_id\": 456,\n",[694,732,734],{"class":696,"line":733},7,[694,735,736],{},"        \"customer_id\": 789,\n",[694,738,740],{"class":696,"line":739},8,[694,741,742],{},"        \"total\": 199.90,\n",[694,744,746],{"class":696,"line":745},9,[694,747,748],{},"        \"items\": [{\"product_id\": 1, \"qty\": 2}]\n",[694,750,752],{"class":696,"line":751},10,[694,753,754],{},"    },\n",[694,756,758],{"class":696,"line":757},11,[694,759,760],{},"    \"timestamp\": \"2026-08-26T10:00:00Z\"\n",[694,762,764],{"class":696,"line":763},12,[694,765,766],{},"}\n",[694,768,770],{"class":696,"line":769},13,[694,771,773],{"emptyLinePlaceholder":772},true,"\n",[694,775,777],{"class":696,"line":776},14,[694,778,779],{},"# Publica no Kafka\u002FRabbitMQ — não espera ninguém processar\n",[694,781,783],{"class":696,"line":782},15,[694,784,785],{},"producer.send(\"order-events\", order_created)\n",[694,787,789],{"class":696,"line":788},16,[694,790,773],{"emptyLinePlaceholder":772},[694,792,794],{"class":696,"line":793},17,[694,795,796],{},"# Múltiplos serviços consomem independentemente:\n",[694,798,800],{"class":696,"line":799},18,[694,801,802],{},"# - Serviço de estoque consome → reserva os itens\n",[694,804,806],{"class":696,"line":805},19,[694,807,808],{},"# - Serviço de notificação consome → envia e-mail de confirmação\n",[694,810,812],{"class":696,"line":811},20,[694,813,814],{},"# - Serviço de analytics consome → atualiza dashboard de vendas\n",[694,816,818],{"class":696,"line":817},21,[694,819,820],{},"# Cada um faz sua parte sem depender dos outros\n",[155,822,824],{"id":823},"grpc-para-service-to-service","gRPC para service-to-service",[97,826,827],{},[85,828,829,831,832,835],{},[88,830,103],{},": gRPC é como dois cozinheiros se comunicando por um ",[88,833,834],{},"sistema\nde pedidos digital"," em vez de gritar pela cozinha. Mais rápido, mais\norganizado, e com um \"menu\" definido (contrato) que ambos seguem.",[85,837,838,841],{},[88,839,840],{},"gRPC"," é uma alternativa ao REST para comunicação entre serviços:",[117,843,844,850,856],{},[19,845,846,849],{},[88,847,848],{},"Binário (Protocol Buffers)",": mensagens 3-10x menores que JSON → menos\nbanda, mais rápido",[19,851,852,855],{},[88,853,854],{},"HTTP\u002F2",": suporta multiplexação (múltiplas mensagens em uma conexão) e\nstreaming",[19,857,858,861],{},[88,859,860],{},"Contrato tipado (.proto)",": um arquivo define exatamente os tipos de\ndados → geração automática de código para cliente e servidor",[417,863,867],{"className":864,"code":865,"language":866,"meta":425,"style":425},"language-protobuf shiki shiki-themes github-light github-dark","\u002F\u002F pedido.proto — contrato que define a comunicação\nsyntax = \"proto3\";\n\nservice PedidoService {\n  rpc CriarPedido (CriarPedidoRequest) returns (PedidoResponse);\n  rpc GetPedido (GetPedidoRequest) returns (PedidoResponse);\n}\n\nmessage CriarPedidoRequest {\n  int32 cliente_id = 1;\n  repeated ItemPedido itens = 2;\n}\n\nmessage ItemPedido {\n  int32 produto_id = 1;\n  int32 quantidade = 2;\n}\n\nmessage PedidoResponse {\n  int32 id = 1;\n  string status = 2;\n  double total = 3;\n}\n","protobuf",[384,868,869,874,879,883,888,893,898,902,906,911,916,921,925,929,934,939,944,948,952,957,962,967,973],{"__ignoreMap":425},[694,870,871],{"class":696,"line":697},[694,872,873],{},"\u002F\u002F pedido.proto — contrato que define a comunicação\n",[694,875,876],{"class":696,"line":703},[694,877,878],{},"syntax = \"proto3\";\n",[694,880,881],{"class":696,"line":709},[694,882,773],{"emptyLinePlaceholder":772},[694,884,885],{"class":696,"line":715},[694,886,887],{},"service PedidoService {\n",[694,889,890],{"class":696,"line":721},[694,891,892],{},"  rpc CriarPedido (CriarPedidoRequest) returns (PedidoResponse);\n",[694,894,895],{"class":696,"line":727},[694,896,897],{},"  rpc GetPedido (GetPedidoRequest) returns (PedidoResponse);\n",[694,899,900],{"class":696,"line":733},[694,901,766],{},[694,903,904],{"class":696,"line":739},[694,905,773],{"emptyLinePlaceholder":772},[694,907,908],{"class":696,"line":745},[694,909,910],{},"message CriarPedidoRequest {\n",[694,912,913],{"class":696,"line":751},[694,914,915],{},"  int32 cliente_id = 1;\n",[694,917,918],{"class":696,"line":757},[694,919,920],{},"  repeated ItemPedido itens = 2;\n",[694,922,923],{"class":696,"line":763},[694,924,766],{},[694,926,927],{"class":696,"line":769},[694,928,773],{"emptyLinePlaceholder":772},[694,930,931],{"class":696,"line":776},[694,932,933],{},"message ItemPedido {\n",[694,935,936],{"class":696,"line":782},[694,937,938],{},"  int32 produto_id = 1;\n",[694,940,941],{"class":696,"line":788},[694,942,943],{},"  int32 quantidade = 2;\n",[694,945,946],{"class":696,"line":793},[694,947,766],{},[694,949,950],{"class":696,"line":799},[694,951,773],{"emptyLinePlaceholder":772},[694,953,954],{"class":696,"line":805},[694,955,956],{},"message PedidoResponse {\n",[694,958,959],{"class":696,"line":811},[694,960,961],{},"  int32 id = 1;\n",[694,963,964],{"class":696,"line":817},[694,965,966],{},"  string status = 2;\n",[694,968,970],{"class":696,"line":969},22,[694,971,972],{},"  double total = 3;\n",[694,974,976],{"class":696,"line":975},23,[694,977,766],{},[97,979,980],{},[85,981,982,985],{},[88,983,984],{},"Quando usar gRPC vs REST",": REST para APIs externas (clientes, parceiros),\ngRPC para comunicação interna entre serviços (onde performance importa e\nvocê controla ambos os lados).",[11,987,989],{"id":988},"dados-em-microserviços-dados","Dados em microserviços {#dados}",[85,991,992,995,996,999],{},[88,993,994],{},"Princípio fundamental",": cada microserviço é ",[88,997,998],{},"dono do seu banco de dados",".\nNenhum serviço acessa o banco de outro diretamente.",[97,1001,1002],{},[85,1003,1004,1006],{},[88,1005,103],{},": Em uma empresa, o setor financeiro tem seus arquivos, o RH tem\nos seus. O financeiro não vai mexer nos arquivos do RH diretamente — se\nprecisa de informação, pede ao RH. Em microserviços é igual: se o serviço\nA precisa de dados do serviço B, ele pede via API\u002Feventos, não acessa o\nbanco do B diretamente.",[97,1008,1009],{},[85,1010,1011,1014],{},[88,1012,1013],{},"Por que?",": Se dois serviços compartilham o banco, uma mudança na tabela\nde um afeta o outro. Você perde o isolamento — a principal vantagem dos\nmicroserviços.",[155,1016,1018],{"id":1017},"padrões-de-dados","Padrões de dados",[160,1020,1021,1034],{},[163,1022,1023],{},[166,1024,1025,1028,1031],{},[169,1026,1027],{},"Padrão",[169,1029,1030],{},"Quando usar",[169,1032,1033],{},"Trade-off",[178,1035,1036,1049,1062,1076,1089],{},[166,1037,1038,1043,1046],{},[183,1039,1040],{},[88,1041,1042],{},"Database per service",[183,1044,1045],{},"Padrão default (cada serviço tem seu banco)",[183,1047,1048],{},"Isolamento total, mas consultas que cruzam serviços são complexas",[166,1050,1051,1056,1059],{},[183,1052,1053],{},[88,1054,1055],{},"Shared database",[183,1057,1058],{},"Transição gradual de monolito",[183,1060,1061],{},"Rápido para migrar, mas quebra o isolamento",[166,1063,1064,1070,1073],{},[183,1065,1066,1069],{},[88,1067,1068],{},"CQRS"," (Command Query Responsibility Segregation)",[183,1071,1072],{},"Leitura e escrita têm necessidades diferentes",[183,1074,1075],{},"Otimiza cada lado, mas adiciona complexidade",[166,1077,1078,1083,1086],{},[183,1079,1080],{},[88,1081,1082],{},"Event Sourcing",[183,1084,1085],{},"Precisa de auditoria completa de todas as mudanças",[183,1087,1088],{},"Permite \"replay\" da história, mas o storage cresce indefinidamente",[166,1090,1091,1095,1098],{},[183,1092,1093],{},[88,1094,551],{},[183,1096,1097],{},"Transação que envolve múltiplos serviços",[183,1099,1100],{},"Consistência eventual (não imediata), exige compensação",[97,1102,1103],{},[85,1104,1105,1108,1109,1112,1113,1116],{},[88,1106,1107],{},"O que é CQRS?",": Separa operações de ",[88,1110,1111],{},"escrita"," (Command — criar,\natualizar, deletar) de ",[88,1114,1115],{},"leitura"," (Query — buscar, listar). Em vez de um\núnico modelo para ambos, você tem um modelo otimizado para escrita (normalizado,\ntransacional) e outro otimizado para leitura (desnormalizado, rápido para\nconsultas).",[97,1118,1119],{},[85,1120,1121,1124,1125,1128],{},[88,1122,1123],{},"O que é Event Sourcing?",": Em vez de guardar apenas o estado atual\n(\"saldo = R$ 1.000\"), guarda ",[88,1126,1127],{},"todos os eventos"," que levaram a esse estado\n(\"+500 depósito, -200 saque, +700 depósito\"). Permite reconstruir o estado\na qualquer momento e auditar toda a história. Mas o armazenamento cresce\npara sempre.",[155,1130,1132],{"id":1131},"sincronização-de-dados","Sincronização de dados",[85,1134,1135],{},"Quando um serviço precisa de dados de outro, há 3 abordagens:",[16,1137,1138,1144,1154],{},[19,1139,1140,1143],{},[88,1141,1142],{},"API call"," (chamada direta): simples, mas cria acoplamento temporal\n(se o serviço B cai, A não consegue obter os dados)",[19,1145,1146,1149,1150,1153],{},[88,1147,1148],{},"Réplica de leitura",": copia dados via ",[88,1151,1152],{},"CDC"," (Change Data Capture —\ncaptura mudanças do banco de B e replica para uma cópia de leitura de A)\n→ rápido, mas os dados são eventualmente consistentes (podem estar\nalguns segundos desatualizados)",[19,1155,1156,1159],{},[88,1157,1158],{},"Materialized view"," (visão materializada): agregação pré-computada\n→ rápido para consultas complexas, mas precisa ser atualizada periodicamente",[11,1161,1163],{"id":1162},"deploy-e-orquestração-deploy","Deploy e orquestração {#deploy}",[155,1165,1167],{"id":1166},"kubernetes-o-padrão-de-facto","Kubernetes: o padrão de facto",[97,1169,1170],{},[85,1171,1172,628,1174,1177,1178,1181,1182,1185],{},[88,1173,103],{},[88,1175,1176],{},"Kubernetes"," (frequentemente abreviado como ",[88,1179,1180],{},"K8s",") é como\num ",[88,1183,1184],{},"gerente de fábrica",". Você diz \"quero 3 instâncias do serviço de\npedidos rodando, cada uma usando no máximo 512MB de memória\". O Kubernetes\ngarante que isso aconteça: se uma instância cai, ele cria outra. Se o\ntráfego aumenta, ele cria mais instâncias. Se diminui, ele remove. Tudo\nautomaticamente.",[85,1187,1188],{},"Kubernetes é o padrão da indústria para orquestrar contêineres (aplicações\nempacotadas com tudo que precisam para rodar). Veja um exemplo de configuração:",[417,1190,1194],{"className":1191,"code":1192,"language":1193,"meta":425,"style":425},"language-yaml shiki shiki-themes github-light github-dark","# deployment.yaml — Define como o serviço de pedidos deve rodar\napiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: order-service\nspec:\n  replicas: 3                    # sempre 3 instâncias rodando (alta disponibilidade)\n  selector:\n    matchLabels:\n      app: order-service\n  template:\n    spec:\n      containers:\n        - name: order-service\n          image: registry.com\u002Forder-service:v1.4.2  # versão da imagem\n          resources:\n            # 'requests' = mínimo garantido (K8s reserva isto)\n            requests:\n              memory: \"256Mi\"     # 256 MB de memória\n              cpu: \"250m\"         # 0.25 CPU (1 CPU = 1000m)\n            # 'limits' = máximo permitido (K8s limita a isto)\n            limits:\n              memory: \"512Mi\"     # até 512 MB\n              cpu: \"500m\"         # até 0.5 CPU\n          # Liveness: \"este serviço está vivo?\" — se falhar, K8s reinicia\n          livenessProbe:\n            httpGet:\n              path: \u002Fhealth       # endpoint que retorna 200 se saudável\n              port: 8080\n          # Readiness: \"este serviço está pronto para receber tráfego?\"\n          # — se falhar, K8s tira do load balancer mas não reinicia\n          readinessProbe:\n            httpGet:\n              path: \u002Fready        # endpoint que retorna 200 se pronto\n              port: 8080\n","yaml",[384,1195,1196,1202,1215,1225,1233,1243,1250,1264,1271,1278,1287,1294,1301,1308,1320,1333,1340,1345,1352,1365,1378,1383,1390,1402,1415,1421,1429,1437,1451,1462,1468,1474,1482,1489,1502],{"__ignoreMap":425},[694,1197,1198],{"class":696,"line":697},[694,1199,1201],{"class":1200},"sJ8bj","# deployment.yaml — Define como o serviço de pedidos deve rodar\n",[694,1203,1204,1208,1211],{"class":696,"line":703},[694,1205,1207],{"class":1206},"s9eBZ","apiVersion",[694,1209,628],{"class":1210},"sVt8B",[694,1212,1214],{"class":1213},"sZZnC","apps\u002Fv1\n",[694,1216,1217,1220,1222],{"class":696,"line":709},[694,1218,1219],{"class":1206},"kind",[694,1221,628],{"class":1210},[694,1223,1224],{"class":1213},"Deployment\n",[694,1226,1227,1230],{"class":696,"line":715},[694,1228,1229],{"class":1206},"metadata",[694,1231,1232],{"class":1210},":\n",[694,1234,1235,1238,1240],{"class":696,"line":721},[694,1236,1237],{"class":1206},"  name",[694,1239,628],{"class":1210},[694,1241,1242],{"class":1213},"order-service\n",[694,1244,1245,1248],{"class":696,"line":727},[694,1246,1247],{"class":1206},"spec",[694,1249,1232],{"class":1210},[694,1251,1252,1255,1257,1261],{"class":696,"line":733},[694,1253,1254],{"class":1206},"  replicas",[694,1256,628],{"class":1210},[694,1258,1260],{"class":1259},"sj4cs","3",[694,1262,1263],{"class":1200},"                    # sempre 3 instâncias rodando (alta disponibilidade)\n",[694,1265,1266,1269],{"class":696,"line":739},[694,1267,1268],{"class":1206},"  selector",[694,1270,1232],{"class":1210},[694,1272,1273,1276],{"class":696,"line":745},[694,1274,1275],{"class":1206},"    matchLabels",[694,1277,1232],{"class":1210},[694,1279,1280,1283,1285],{"class":696,"line":751},[694,1281,1282],{"class":1206},"      app",[694,1284,628],{"class":1210},[694,1286,1242],{"class":1213},[694,1288,1289,1292],{"class":696,"line":757},[694,1290,1291],{"class":1206},"  template",[694,1293,1232],{"class":1210},[694,1295,1296,1299],{"class":696,"line":763},[694,1297,1298],{"class":1206},"    spec",[694,1300,1232],{"class":1210},[694,1302,1303,1306],{"class":696,"line":769},[694,1304,1305],{"class":1206},"      containers",[694,1307,1232],{"class":1210},[694,1309,1310,1313,1316,1318],{"class":696,"line":776},[694,1311,1312],{"class":1210},"        - ",[694,1314,1315],{"class":1206},"name",[694,1317,628],{"class":1210},[694,1319,1242],{"class":1213},[694,1321,1322,1325,1327,1330],{"class":696,"line":782},[694,1323,1324],{"class":1206},"          image",[694,1326,628],{"class":1210},[694,1328,1329],{"class":1213},"registry.com\u002Forder-service:v1.4.2",[694,1331,1332],{"class":1200},"  # versão da imagem\n",[694,1334,1335,1338],{"class":696,"line":788},[694,1336,1337],{"class":1206},"          resources",[694,1339,1232],{"class":1210},[694,1341,1342],{"class":696,"line":793},[694,1343,1344],{"class":1200},"            # 'requests' = mínimo garantido (K8s reserva isto)\n",[694,1346,1347,1350],{"class":696,"line":799},[694,1348,1349],{"class":1206},"            requests",[694,1351,1232],{"class":1210},[694,1353,1354,1357,1359,1362],{"class":696,"line":805},[694,1355,1356],{"class":1206},"              memory",[694,1358,628],{"class":1210},[694,1360,1361],{"class":1213},"\"256Mi\"",[694,1363,1364],{"class":1200},"     # 256 MB de memória\n",[694,1366,1367,1370,1372,1375],{"class":696,"line":811},[694,1368,1369],{"class":1206},"              cpu",[694,1371,628],{"class":1210},[694,1373,1374],{"class":1213},"\"250m\"",[694,1376,1377],{"class":1200},"         # 0.25 CPU (1 CPU = 1000m)\n",[694,1379,1380],{"class":696,"line":817},[694,1381,1382],{"class":1200},"            # 'limits' = máximo permitido (K8s limita a isto)\n",[694,1384,1385,1388],{"class":696,"line":969},[694,1386,1387],{"class":1206},"            limits",[694,1389,1232],{"class":1210},[694,1391,1392,1394,1396,1399],{"class":696,"line":975},[694,1393,1356],{"class":1206},[694,1395,628],{"class":1210},[694,1397,1398],{"class":1213},"\"512Mi\"",[694,1400,1401],{"class":1200},"     # até 512 MB\n",[694,1403,1405,1407,1409,1412],{"class":696,"line":1404},24,[694,1406,1369],{"class":1206},[694,1408,628],{"class":1210},[694,1410,1411],{"class":1213},"\"500m\"",[694,1413,1414],{"class":1200},"         # até 0.5 CPU\n",[694,1416,1418],{"class":696,"line":1417},25,[694,1419,1420],{"class":1200},"          # Liveness: \"este serviço está vivo?\" — se falhar, K8s reinicia\n",[694,1422,1424,1427],{"class":696,"line":1423},26,[694,1425,1426],{"class":1206},"          livenessProbe",[694,1428,1232],{"class":1210},[694,1430,1432,1435],{"class":696,"line":1431},27,[694,1433,1434],{"class":1206},"            httpGet",[694,1436,1232],{"class":1210},[694,1438,1440,1443,1445,1448],{"class":696,"line":1439},28,[694,1441,1442],{"class":1206},"              path",[694,1444,628],{"class":1210},[694,1446,1447],{"class":1213},"\u002Fhealth",[694,1449,1450],{"class":1200},"       # endpoint que retorna 200 se saudável\n",[694,1452,1454,1457,1459],{"class":696,"line":1453},29,[694,1455,1456],{"class":1206},"              port",[694,1458,628],{"class":1210},[694,1460,1461],{"class":1259},"8080\n",[694,1463,1465],{"class":696,"line":1464},30,[694,1466,1467],{"class":1200},"          # Readiness: \"este serviço está pronto para receber tráfego?\"\n",[694,1469,1471],{"class":696,"line":1470},31,[694,1472,1473],{"class":1200},"          # — se falhar, K8s tira do load balancer mas não reinicia\n",[694,1475,1477,1480],{"class":696,"line":1476},32,[694,1478,1479],{"class":1206},"          readinessProbe",[694,1481,1232],{"class":1210},[694,1483,1485,1487],{"class":696,"line":1484},33,[694,1486,1434],{"class":1206},[694,1488,1232],{"class":1210},[694,1490,1492,1494,1496,1499],{"class":696,"line":1491},34,[694,1493,1442],{"class":1206},[694,1495,628],{"class":1210},[694,1497,1498],{"class":1213},"\u002Fready",[694,1500,1501],{"class":1200},"        # endpoint que retorna 200 se pronto\n",[694,1503,1505,1507,1509],{"class":696,"line":1504},35,[694,1506,1456],{"class":1206},[694,1508,628],{"class":1210},[694,1510,1461],{"class":1259},[97,1512,1513],{},[85,1514,1515,1518],{},[88,1516,1517],{},"Diferença entre Liveness e Readiness",": Liveness verifica se a aplicação\nestá rodando (se falhar, reinicia). Readiness verifica se está pronta para\nreceber requisições (ex: terminou de carregar configurações, conectou ao\nbanco). Se readiness falhar, o serviço fica fora do balanceador de carga\nmas não é reiniciado.",[155,1520,1522],{"id":1521},"estratégias-de-deploy","Estratégias de deploy",[160,1524,1525,1537],{},[163,1526,1527],{},[166,1528,1529,1532,1535],{},[169,1530,1531],{},"Estratégia",[169,1533,1534],{},"Como funciona",[169,1536,1030],{},[178,1538,1539,1552,1565,1578],{},[166,1540,1541,1546,1549],{},[183,1542,1543],{},[88,1544,1545],{},"Rolling",[183,1547,1548],{},"Substitui instâncias gradualmente (1 por vez)",[183,1550,1551],{},"Default, sem downtime",[166,1553,1554,1559,1562],{},[183,1555,1556],{},[88,1557,1558],{},"Blue\u002FGreen",[183,1560,1561],{},"Dois ambientes idênticos; switch de tráfego instantâneo",[183,1563,1564],{},"Validação rápida com rollback fácil",[166,1566,1567,1572,1575],{},[183,1568,1569],{},[88,1570,1571],{},"Canary",[183,1573,1574],{},"5% → 25% → 50% → 100% do tráfego na nova versão",[183,1576,1577],{},"Risco de regressão alto",[166,1579,1580,1585,1588],{},[183,1581,1582],{},[88,1583,1584],{},"Feature flags",[183,1586,1587],{},"Liga\u002Fdesliga funcionalidade sem novo deploy",[183,1589,1590],{},"Experimentação A\u002FB, rollout controlado",[97,1592,1593],{},[85,1594,1595,1598],{},[88,1596,1597],{},"Analogia Blue\u002FGreen",": É como ter dois palcos de teatro idênticos. A peça\nrola no palco Azul. Você prepara a nova versão no palco Verde. Quando tudo\nestá pronto, muda a plateia do Azul para o Verde instantaneamente. Se algo\nder errado, muda de volta num segundo.",[97,1600,1601],{},[85,1602,1603,1606],{},[88,1604,1605],{},"Analogia Canary",": É como enviar uma nova receita para 5% dos clientes\nprimeiro. Se ninguém reclama, envia para 25%. Se alguém reclama, para. Se\nestá tudo bem, continua até 100%. O nome vem dos canários que mineiros\nlevavam para dentro das minas — se o canário morria, era sinal de gás\ntóxico e todos evacuavam.",[155,1608,1610],{"id":1609},"auto-scaling","Auto-scaling",[417,1612,1614],{"className":1191,"code":1613,"language":1193,"meta":425,"style":425},"# hpa.yaml — Horizontal Pod Autoscaler: escala automaticamente\napiVersion: autoscaling\u002Fv2\nkind: HorizontalPodAutoscaler\nmetadata:\n  name: order-service-hpa\nspec:\n  scaleTargetRef:\n    kind: Deployment\n    name: order-service\n  minReplicas: 3               # mínimo de 3 instâncias (sempre)\n  maxReplicas: 50              # máximo de 50 instâncias\n  metrics:\n    - type: Resource\n      resource:\n        name: cpu\n        target:\n          type: Utilization\n          averageUtilization: 70  # se CPU médio > 70%, cria mais instâncias\n",[384,1615,1616,1621,1630,1639,1645,1654,1660,1667,1676,1685,1697,1710,1717,1730,1737,1747,1754,1764],{"__ignoreMap":425},[694,1617,1618],{"class":696,"line":697},[694,1619,1620],{"class":1200},"# hpa.yaml — Horizontal Pod Autoscaler: escala automaticamente\n",[694,1622,1623,1625,1627],{"class":696,"line":703},[694,1624,1207],{"class":1206},[694,1626,628],{"class":1210},[694,1628,1629],{"class":1213},"autoscaling\u002Fv2\n",[694,1631,1632,1634,1636],{"class":696,"line":709},[694,1633,1219],{"class":1206},[694,1635,628],{"class":1210},[694,1637,1638],{"class":1213},"HorizontalPodAutoscaler\n",[694,1640,1641,1643],{"class":696,"line":715},[694,1642,1229],{"class":1206},[694,1644,1232],{"class":1210},[694,1646,1647,1649,1651],{"class":696,"line":721},[694,1648,1237],{"class":1206},[694,1650,628],{"class":1210},[694,1652,1653],{"class":1213},"order-service-hpa\n",[694,1655,1656,1658],{"class":696,"line":727},[694,1657,1247],{"class":1206},[694,1659,1232],{"class":1210},[694,1661,1662,1665],{"class":696,"line":733},[694,1663,1664],{"class":1206},"  scaleTargetRef",[694,1666,1232],{"class":1210},[694,1668,1669,1672,1674],{"class":696,"line":739},[694,1670,1671],{"class":1206},"    kind",[694,1673,628],{"class":1210},[694,1675,1224],{"class":1213},[694,1677,1678,1681,1683],{"class":696,"line":745},[694,1679,1680],{"class":1206},"    name",[694,1682,628],{"class":1210},[694,1684,1242],{"class":1213},[694,1686,1687,1690,1692,1694],{"class":696,"line":751},[694,1688,1689],{"class":1206},"  minReplicas",[694,1691,628],{"class":1210},[694,1693,1260],{"class":1259},[694,1695,1696],{"class":1200},"               # mínimo de 3 instâncias (sempre)\n",[694,1698,1699,1702,1704,1707],{"class":696,"line":757},[694,1700,1701],{"class":1206},"  maxReplicas",[694,1703,628],{"class":1210},[694,1705,1706],{"class":1259},"50",[694,1708,1709],{"class":1200},"              # máximo de 50 instâncias\n",[694,1711,1712,1715],{"class":696,"line":763},[694,1713,1714],{"class":1206},"  metrics",[694,1716,1232],{"class":1210},[694,1718,1719,1722,1725,1727],{"class":696,"line":769},[694,1720,1721],{"class":1210},"    - ",[694,1723,1724],{"class":1206},"type",[694,1726,628],{"class":1210},[694,1728,1729],{"class":1213},"Resource\n",[694,1731,1732,1735],{"class":696,"line":776},[694,1733,1734],{"class":1206},"      resource",[694,1736,1232],{"class":1210},[694,1738,1739,1742,1744],{"class":696,"line":782},[694,1740,1741],{"class":1206},"        name",[694,1743,628],{"class":1210},[694,1745,1746],{"class":1213},"cpu\n",[694,1748,1749,1752],{"class":696,"line":788},[694,1750,1751],{"class":1206},"        target",[694,1753,1232],{"class":1210},[694,1755,1756,1759,1761],{"class":696,"line":793},[694,1757,1758],{"class":1206},"          type",[694,1760,628],{"class":1210},[694,1762,1763],{"class":1213},"Utilization\n",[694,1765,1766,1769,1771,1774],{"class":696,"line":799},[694,1767,1768],{"class":1206},"          averageUtilization",[694,1770,628],{"class":1210},[694,1772,1773],{"class":1259},"70",[694,1775,1776],{"class":1200},"  # se CPU médio > 70%, cria mais instâncias\n",[97,1778,1779],{},[85,1780,1781,1783],{},[88,1782,1534],{},": O Kubernetes monitora o uso de CPU. Se a média passa de\n70%, ele cria mais instâncias para dividir a carga. Se cai, ele remove\ninstâncias para economizar. Tudo automático, 24\u002F7.",[11,1785,1787],{"id":1786},"observabilidade-observabilidade","Observabilidade {#observabilidade}",[85,1789,1790,1792],{},[88,1791,61],{}," é a capacidade de entender o estado interno do sistema\nobservando suas saídas (logs, métricas, traces). Sem ela, gerenciar\nmicroserviços é como dirigir de olhos vendados.",[97,1794,1795],{},[85,1796,1797,1799,1800,1803],{},[88,1798,103],{},": Observabilidade é o ",[88,1801,1802],{},"painel do carro + GPS + câmera de ré",".\nLogs são o histórico de manutenção. Métricas são o painel (velocímetro,\ntemperatura, combustível). Traces são o GPS que mostra o caminho completo\nde cada viagem.",[85,1805,1806],{},"Os três pilares:",[155,1808,1810],{"id":1809},"_1-logs-estruturados","1. Logs estruturados",[417,1812,1816],{"className":1813,"code":1814,"language":1815,"meta":425,"style":425},"language-json shiki shiki-themes github-light github-dark","{\n  \"timestamp\": \"2026-08-26T10:30:00.123Z\",\n  \"level\": \"info\",\n  \"service\": \"order-service\",\n  \"trace_id\": \"abc123\",         # ID que rastreia a requisição em todos os serviços\n  \"span_id\": \"def456\",          # ID deste trecho específico\n  \"message\": \"Order created\",\n  \"order_id\": 456,\n  \"customer_id\": 789,\n  \"latency_ms\": 142\n}\n","json",[384,1817,1818,1823,1836,1848,1860,1904,1930,1942,1954,1966,1976],{"__ignoreMap":425},[694,1819,1820],{"class":696,"line":697},[694,1821,1822],{"class":1210},"{\n",[694,1824,1825,1828,1830,1833],{"class":696,"line":703},[694,1826,1827],{"class":1259},"  \"timestamp\"",[694,1829,628],{"class":1210},[694,1831,1832],{"class":1213},"\"2026-08-26T10:30:00.123Z\"",[694,1834,1835],{"class":1210},",\n",[694,1837,1838,1841,1843,1846],{"class":696,"line":709},[694,1839,1840],{"class":1259},"  \"level\"",[694,1842,628],{"class":1210},[694,1844,1845],{"class":1213},"\"info\"",[694,1847,1835],{"class":1210},[694,1849,1850,1853,1855,1858],{"class":696,"line":715},[694,1851,1852],{"class":1259},"  \"service\"",[694,1854,628],{"class":1210},[694,1856,1857],{"class":1213},"\"order-service\"",[694,1859,1835],{"class":1210},[694,1861,1862,1865,1867,1870,1873,1877,1880,1883,1886,1889,1892,1895,1898,1901],{"class":696,"line":721},[694,1863,1864],{"class":1259},"  \"trace_id\"",[694,1866,628],{"class":1210},[694,1868,1869],{"class":1213},"\"abc123\"",[694,1871,1872],{"class":1210},",         ",[694,1874,1876],{"class":1875},"s7hpK","#",[694,1878,1879],{"class":1875}," ID",[694,1881,1882],{"class":1875}," que",[694,1884,1885],{"class":1875}," rastreia",[694,1887,1888],{"class":1875}," a",[694,1890,1891],{"class":1875}," requisição",[694,1893,1894],{"class":1875}," em",[694,1896,1897],{"class":1875}," todos",[694,1899,1900],{"class":1875}," os",[694,1902,1903],{"class":1875}," serviços\n",[694,1905,1906,1909,1911,1914,1917,1919,1921,1924,1927],{"class":696,"line":727},[694,1907,1908],{"class":1259},"  \"span_id\"",[694,1910,628],{"class":1210},[694,1912,1913],{"class":1213},"\"def456\"",[694,1915,1916],{"class":1210},",          ",[694,1918,1876],{"class":1875},[694,1920,1879],{"class":1875},[694,1922,1923],{"class":1875}," deste",[694,1925,1926],{"class":1875}," trecho",[694,1928,1929],{"class":1875}," específico\n",[694,1931,1932,1935,1937,1940],{"class":696,"line":733},[694,1933,1934],{"class":1259},"  \"message\"",[694,1936,628],{"class":1210},[694,1938,1939],{"class":1213},"\"Order created\"",[694,1941,1835],{"class":1210},[694,1943,1944,1947,1949,1952],{"class":696,"line":739},[694,1945,1946],{"class":1259},"  \"order_id\"",[694,1948,628],{"class":1210},[694,1950,1951],{"class":1259},"456",[694,1953,1835],{"class":1210},[694,1955,1956,1959,1961,1964],{"class":696,"line":745},[694,1957,1958],{"class":1259},"  \"customer_id\"",[694,1960,628],{"class":1210},[694,1962,1963],{"class":1259},"789",[694,1965,1835],{"class":1210},[694,1967,1968,1971,1973],{"class":696,"line":751},[694,1969,1970],{"class":1259},"  \"latency_ms\"",[694,1972,628],{"class":1210},[694,1974,1975],{"class":1259},"142\n",[694,1977,1978],{"class":696,"line":757},[694,1979,766],{"class":1210},[85,1981,1982,1985],{},[88,1983,1984],{},"Stack",": Fluentd\u002FFluent Bit (coleta) → Elasticsearch\u002FLoki (armazenamento)\n→ Kibana\u002FGrafana (visualização)",[97,1987,1988],{},[85,1989,1990,1993],{},[88,1991,1992],{},"Por que estruturado?",": Logs em texto livre (\"Order 456 created in 142ms\")\nsão difíceis de buscar e filtrar. Logs em JSON permitem queries como\n\"mostre todos os logs onde service=order-service AND latency_ms > 500\".",[155,1995,1997],{"id":1996},"_2-métricas-prometheus-grafana","2. Métricas (Prometheus + Grafana)",[117,1999,2000,2006,2012],{},[19,2001,2002,2005],{},[88,2003,2004],{},"Prometheus"," coleta métricas de cada serviço periodicamente",[19,2007,2008,2011],{},[88,2009,2010],{},"Grafana"," visualiza dashboards em tempo real",[19,2013,2014,2017],{},[88,2015,2016],{},"Alertas",": erro rate, latência P99, saturação de recursos",[85,2019,2020],{},[88,2021,2022],{},"Métricas essenciais (frameworks USE e RED):",[117,2024,2025,2043],{},[19,2026,2027,2030,2031,2034,2035,2038,2039,2042],{},[88,2028,2029],{},"RED"," (por serviço): ",[88,2032,2033],{},"R","ate (taxa de requisições), ",[88,2036,2037],{},"E","rrors (taxa de\nerro), ",[88,2040,2041],{},"D","uration (latência)",[19,2044,2045,2048,2049,2052,2053,2056,2057,2059],{},[88,2046,2047],{},"USE"," (por recurso): ",[88,2050,2051],{},"U","tilization (utilização), ",[88,2054,2055],{},"S","aturation\n(saturação), ",[88,2058,2037],{},"rrors (erros)",[155,2061,2063],{"id":2062},"_3-distributed-tracing","3. Distributed tracing",[97,2065,2066],{},[85,2067,2068,2070,2071,2074],{},[88,2069,103],{},": Distributed tracing é como o ",[88,2072,2073],{},"rastreamento de encomenda"," dos\ncorreios. Você vê cada passo: saiu do centro de distribuição → chegou na\nunidade de triagem → saiu para entrega → entregue. Com timestamps em cada\netapa, você vê onde demorou mais.",[85,2076,2077,2080,2081,2084],{},[88,2078,2079],{},"OpenTelemetry"," instrumenta cada serviço. ",[88,2082,2083],{},"Jaeger\u002FTempo"," visualiza o\ntrace completo de uma requisição:",[417,2086,2089],{"className":2087,"code":2088,"language":422},[420],"[Gateway] → [Auth] → [Order] → [Inventory] → [Payment]\n  2ms        15ms     45ms       30ms         50ms\n                                        Total: 142ms\n",[384,2090,2088],{"__ignoreMap":425},[97,2092,2093],{},[85,2094,2095,2098],{},[88,2096,2097],{},"Por que isso importa?",": Um cliente reclama \"a compra demorou 10 segundos\".\nSem distributed tracing, você não sabe qual dos 5 serviços é o culpado. Com\ntracing, você vê imediatamente: o serviço de Inventory demorou 8 segundos.",[11,2100,2102],{"id":2101},"escala-real-números-numeros","Escala real: números {#numeros}",[160,2104,2105,2118],{},[163,2106,2107],{},[166,2108,2109,2112,2115],{},[169,2110,2111],{},"Volume",[169,2113,2114],{},"Arquitetura recomendada",[169,2116,2117],{},"Infraestrutura",[178,2119,2120,2130,2141,2152,2163],{},[166,2121,2122,2125,2127],{},[183,2123,2124],{},"1K req\u002Fdia",[183,2126,174],{},[183,2128,2129],{},"1 instância (t3.small)",[166,2131,2132,2135,2138],{},[183,2133,2134],{},"10K req\u002Fdia",[183,2136,2137],{},"Monolito modular",[183,2139,2140],{},"2 instâncias + Load Balancer",[166,2142,2143,2146,2149],{},[183,2144,2145],{},"100K req\u002Fdia",[183,2147,2148],{},"2-3 serviços",[183,2150,2151],{},"3-5 pods + Redis cache",[166,2153,2154,2157,2160],{},[183,2155,2156],{},"1M req\u002Fdia",[183,2158,2159],{},"5-10 microserviços",[183,2161,2162],{},"K8s + auto-scaling + Kafka",[166,2164,2165,2168,2171],{},[183,2166,2167],{},"10M req\u002Fdia",[183,2169,2170],{},"15-30 microserviços",[183,2172,2173],{},"K8s multi-AZ + CDN + event-driven",[97,2175,2176],{},[85,2177,2178,2180],{},[88,2179,103],{},": Você não constrói um shopping center para uma banca de jornal.\nCada volume de tráfego pede uma arquitetura diferente. Comece pequeno e\nevolua conforme o negócio cresce.",[155,2182,2184],{"id":2183},"custos-aproximados-aws-2026","Custos aproximados (AWS, 2026)",[160,2186,2187,2200],{},[163,2188,2189],{},[166,2190,2191,2194,2197],{},[169,2192,2193],{},"Fase",[169,2195,2196],{},"Tráfego",[169,2198,2199],{},"Custo\u002Fmês",[178,2201,2202,2212,2222,2231],{},[166,2203,2204,2207,2209],{},[183,2205,2206],{},"MVP",[183,2208,2124],{},[183,2210,2211],{},"$20-50",[166,2213,2214,2217,2219],{},[183,2215,2216],{},"Crescimento",[183,2218,2145],{},[183,2220,2221],{},"$200-500",[166,2223,2224,2226,2228],{},[183,2225,218],{},[183,2227,2156],{},[183,2229,2230],{},"$1.000-3.000",[166,2232,2233,2236,2238],{},[183,2234,2235],{},"Alta escala",[183,2237,2167],{},[183,2239,2240],{},"$5.000-15.000",[97,2242,2243,2249],{},[85,2244,2245,2248],{},[88,2246,2247],{},"Dica",": Otimize custos com:",[117,2250,2251,2257,2263],{},[19,2252,2253,2256],{},[88,2254,2255],{},"Auto-scaling agressivo",": reduz instâncias quando o tráfego cai (à noite,\nfins de semana)",[19,2258,2259,2262],{},[88,2260,2261],{},"Spot Instances",": instâncias mais baratas (até 90% de desconto) para\nworkloads que toleram interrupção (processamento em batch, por exemplo)",[19,2264,2265,2268],{},[88,2266,2267],{},"CDN"," (CloudFront): reduz carga na origem servindo conteúdo estático\npela borda (mais próximo do usuário)",[11,2270,2272],{"id":2271},"erros-comuns-erros","Erros comuns {#erros}",[155,2274,2276],{"id":2275},"erro-1-começar-com-microserviços-no-mvp","Erro 1: Começar com microserviços no MVP",[85,2278,2279,2282],{},[88,2280,2281],{},"O que acontece",": A startup decide começar já com microserviços \"para não\nprecisar migrar depois\". 3 desenvolvedores gastam 4 meses configurando\nKubernetes, service mesh e CI\u002FCD antes de ter um único usuário.",[85,2284,2285,2288],{},[88,2286,2287],{},"O que NÃO fazer",":",[417,2290,2293],{"className":2291,"code":2292,"language":422},[420],"❌ Dia 1 da startup, 0 usuários, 0 receita:\n- 8 microserviços\n- Kubernetes com Istio\n- Kafka para eventos\n- CI\u002FCD com ArgoCD\n- Observabilidade com 5 ferramentas\n\nResultado: 4 meses de setup, nenhuma feature para o usuário, dinheiro acabando.\n",[384,2294,2292],{"__ignoreMap":425},[85,2296,2297,2288],{},[88,2298,2299],{},"O que fazer",[417,2301,2304],{"className":2302,"code":2303,"language":422},[420],"✅ Dia 1 da startup:\n- 1 monolito modular (Node.js ou Python)\n- 1 banco de dados (PostgreSQL)\n- 1 instância (Railway ou Fly.io)\n- Deploy com git push\n\nQuando tiver 100K+ req\u002Fdia e 8+ desenvolvedores:\n- Aí sim, extraia microserviços conforme a necessidade\n",[384,2305,2303],{"__ignoreMap":425},[155,2307,2309],{"id":2308},"erro-2-compartilhar-banco-de-dados-entre-serviços","Erro 2: Compartilhar banco de dados entre serviços",[85,2311,2312,2314],{},[88,2313,2281],{},": Dois microserviços acessam o mesmo banco \"para facilitar\njoins\". Uma mudança na tabela de um serviço quebra o outro. Os serviços não\nsão realmente independentes.",[85,2316,2317,2288],{},[88,2318,2287],{},[417,2320,2322],{"className":688,"code":2321,"language":690,"meta":425,"style":425},"# ❌ ERRADO: serviço de pedidos acessa o banco de clientes diretamente\ndef get_pedido_com_cliente(pedido_id):\n    pedido = db_pedidos.query(\"SELECT * FROM pedidos WHERE id = ?\", pedido_id)\n    # Acessando diretamente a tabela de clientes — quebra o isolamento!\n    cliente = db_pedidos.query(\"SELECT * FROM clientes WHERE id = ?\", pedido.cliente_id)\n    return {**pedido, \"cliente\": cliente}\n",[384,2323,2324,2329,2334,2339,2344,2349],{"__ignoreMap":425},[694,2325,2326],{"class":696,"line":697},[694,2327,2328],{},"# ❌ ERRADO: serviço de pedidos acessa o banco de clientes diretamente\n",[694,2330,2331],{"class":696,"line":703},[694,2332,2333],{},"def get_pedido_com_cliente(pedido_id):\n",[694,2335,2336],{"class":696,"line":709},[694,2337,2338],{},"    pedido = db_pedidos.query(\"SELECT * FROM pedidos WHERE id = ?\", pedido_id)\n",[694,2340,2341],{"class":696,"line":715},[694,2342,2343],{},"    # Acessando diretamente a tabela de clientes — quebra o isolamento!\n",[694,2345,2346],{"class":696,"line":721},[694,2347,2348],{},"    cliente = db_pedidos.query(\"SELECT * FROM clientes WHERE id = ?\", pedido.cliente_id)\n",[694,2350,2351],{"class":696,"line":727},[694,2352,2353],{},"    return {**pedido, \"cliente\": cliente}\n",[85,2355,2356,2288],{},[88,2357,2299],{},[417,2359,2361],{"className":688,"code":2360,"language":690,"meta":425,"style":425},"# ✅ CERTO: serviço de pedidos pede dados de cliente via API do serviço de clientes\ndef get_pedido_com_cliente(pedido_id):\n    pedido = db_pedidos.query(\"SELECT * FROM pedidos WHERE id = ?\", pedido_id)\n    # Pede ao serviço de clientes via API — mantém o isolamento\n    cliente = cliente_service_api.get(pedido.cliente_id)\n    return {**pedido, \"cliente\": cliente}\n",[384,2362,2363,2368,2372,2376,2381,2386],{"__ignoreMap":425},[694,2364,2365],{"class":696,"line":697},[694,2366,2367],{},"# ✅ CERTO: serviço de pedidos pede dados de cliente via API do serviço de clientes\n",[694,2369,2370],{"class":696,"line":703},[694,2371,2333],{},[694,2373,2374],{"class":696,"line":709},[694,2375,2338],{},[694,2377,2378],{"class":696,"line":715},[694,2379,2380],{},"    # Pede ao serviço de clientes via API — mantém o isolamento\n",[694,2382,2383],{"class":696,"line":721},[694,2384,2385],{},"    cliente = cliente_service_api.get(pedido.cliente_id)\n",[694,2387,2388],{"class":696,"line":727},[694,2389,2353],{},[155,2391,2393],{"id":2392},"erro-3-comunicação-síncrona-em-cascata","Erro 3: Comunicação síncrona em cascata",[85,2395,2396,2398],{},[88,2397,2281],{},": O serviço A chama B, que chama C, que chama D. Se D cai,\nC fica esperando, B fica esperando, A fica esperando, e o cliente recebe\ntimeout. Um único serviço derruba toda a cadeia.",[85,2400,2401,2288],{},[88,2402,2287],{},[417,2404,2407],{"className":2405,"code":2406,"language":422},[420],"❌ Cadeia síncrona:\n[Cliente] → [A] → [B] → [C] → [D (caiu)]\n     ← timeout ← timeout ← timeout ← timeout\nTodos os serviços ficam presos esperando D.\n",[384,2408,2406],{"__ignoreMap":425},[85,2410,2411,2288],{},[88,2412,2299],{},[417,2414,2417],{"className":2415,"code":2416,"language":422},[420],"✅ Usar circuit breaker + comunicação assíncrona onde possível:\n[Cliente] → [A] → [B] → [C] → [D (caiu)]\n                    ← circuit breaker \"desarma\" ← fallback imediato\nA responde com dados parciais ou mensagem de \"tente mais tarde\".\n\nOu melhor: [A] publica evento, [B], [C], [D] consomem independentemente.\nNenhum depende do outro estar online.\n",[384,2418,2416],{"__ignoreMap":425},[155,2420,2422],{"id":2421},"erro-4-sem-distributed-tracing","Erro 4: Sem distributed tracing",[85,2424,2425,2427],{},[88,2426,2281],{},": Em produção, um cliente reclama que \"às vezes o checkout\ndemora 15 segundos\". Você tem 6 serviços. Sem distributed tracing, você não\nfaz ideia de qual serviço está lento. Fica testando um por um, por dias.",[85,2429,2430,2432],{},[88,2431,2299],{},": Implemente OpenTelemetry desde o início. O custo de\nimplementar é baixo (algumas linhas de configuração por serviço) e o\nbenefício é enorme quando há problemas em produção.",[417,2434,2436],{"className":688,"code":2435,"language":690,"meta":425,"style":425},"# Exemplo: instrumentação com OpenTelemetry em Python\nfrom opentelemetry import trace\nfrom opentelemetry.instrumentation.fastapi import FastAPIInstrumentor\n\ntracer = trace.get_tracer(__name__)\n\n@app.get(\"\u002Fpedidos\u002F{pedido_id}\")\nasync def get_pedido(pedido_id: int):\n    # Cria um span (trecho do trace) automaticamente\n    with tracer.start_as_current_span(\"get_pedido\") as span:\n        span.set_attribute(\"pedido_id\", pedido_id)\n        \n        pedido = buscar_pedido(pedido_id)  # sub-span automático\n        cliente = buscar_cliente(pedido.cliente_id)  # sub-span automático\n        \n        span.set_attribute(\"cliente_id\", pedido.cliente_id)\n        return {**pedido, \"cliente\": cliente}\n",[384,2437,2438,2443,2448,2453,2457,2462,2466,2471,2476,2481,2486,2491,2496,2501,2506,2510,2515],{"__ignoreMap":425},[694,2439,2440],{"class":696,"line":697},[694,2441,2442],{},"# Exemplo: instrumentação com OpenTelemetry em Python\n",[694,2444,2445],{"class":696,"line":703},[694,2446,2447],{},"from opentelemetry import trace\n",[694,2449,2450],{"class":696,"line":709},[694,2451,2452],{},"from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor\n",[694,2454,2455],{"class":696,"line":715},[694,2456,773],{"emptyLinePlaceholder":772},[694,2458,2459],{"class":696,"line":721},[694,2460,2461],{},"tracer = trace.get_tracer(__name__)\n",[694,2463,2464],{"class":696,"line":727},[694,2465,773],{"emptyLinePlaceholder":772},[694,2467,2468],{"class":696,"line":733},[694,2469,2470],{},"@app.get(\"\u002Fpedidos\u002F{pedido_id}\")\n",[694,2472,2473],{"class":696,"line":739},[694,2474,2475],{},"async def get_pedido(pedido_id: int):\n",[694,2477,2478],{"class":696,"line":745},[694,2479,2480],{},"    # Cria um span (trecho do trace) automaticamente\n",[694,2482,2483],{"class":696,"line":751},[694,2484,2485],{},"    with tracer.start_as_current_span(\"get_pedido\") as span:\n",[694,2487,2488],{"class":696,"line":757},[694,2489,2490],{},"        span.set_attribute(\"pedido_id\", pedido_id)\n",[694,2492,2493],{"class":696,"line":763},[694,2494,2495],{},"        \n",[694,2497,2498],{"class":696,"line":769},[694,2499,2500],{},"        pedido = buscar_pedido(pedido_id)  # sub-span automático\n",[694,2502,2503],{"class":696,"line":776},[694,2504,2505],{},"        cliente = buscar_cliente(pedido.cliente_id)  # sub-span automático\n",[694,2507,2508],{"class":696,"line":782},[694,2509,2495],{},[694,2511,2512],{"class":696,"line":788},[694,2513,2514],{},"        span.set_attribute(\"cliente_id\", pedido.cliente_id)\n",[694,2516,2517],{"class":696,"line":793},[694,2518,2519],{},"        return {**pedido, \"cliente\": cliente}\n",[155,2521,2523],{"id":2522},"erro-5-ignorar-consistência-eventual","Erro 5: Ignorar consistência eventual",[85,2525,2526,2528],{},[88,2527,2281],{},": O serviço de pedidos confirma um pedido, mas o serviço\nde estoque ainda não processou a reserva (fila com atraso). O cliente vê\n\"pedido confirmado\" mas o estoque não foi reservado. Resultado: venda sem\nestoque.",[85,2530,2531,2288],{},[88,2532,2287],{},[417,2534,2536],{"className":688,"code":2535,"language":690,"meta":425,"style":425},"# ❌ ERRADO: assumir que tudo é imediato\ndef criar_pedido(dados):\n    pedido = salvar_pedido(dados)\n    publicar_evento_pedido_criado(pedido)\n    return {\"status\": \"confirmado\"}  # afirma confirmação imediata\n    # Mas estoque ainda pode não ter reservado!\n",[384,2537,2538,2543,2548,2553,2558,2563],{"__ignoreMap":425},[694,2539,2540],{"class":696,"line":697},[694,2541,2542],{},"# ❌ ERRADO: assumir que tudo é imediato\n",[694,2544,2545],{"class":696,"line":703},[694,2546,2547],{},"def criar_pedido(dados):\n",[694,2549,2550],{"class":696,"line":709},[694,2551,2552],{},"    pedido = salvar_pedido(dados)\n",[694,2554,2555],{"class":696,"line":715},[694,2556,2557],{},"    publicar_evento_pedido_criado(pedido)\n",[694,2559,2560],{"class":696,"line":721},[694,2561,2562],{},"    return {\"status\": \"confirmado\"}  # afirma confirmação imediata\n",[694,2564,2565],{"class":696,"line":727},[694,2566,2567],{},"    # Mas estoque ainda pode não ter reservado!\n",[85,2569,2570,2288],{},[88,2571,2299],{},[417,2573,2575],{"className":688,"code":2574,"language":690,"meta":425,"style":425},"# ✅ CERTO: usar Saga e informar status correto\ndef criar_pedido(dados):\n    pedido = salvar_pedido(dados, status=\"processando\")  # não confirmado ainda\n    publicar_evento_pedido_criado(pedido)\n    return {\"status\": \"processando\", \"pedido_id\": pedido.id}\n    # Cliente sabe que está em processamento\n\n# Quando estoque reserva e pagamento confirma:\ndef on_estoque_reservado(evento):\n    if evento.sucesso:\n        atualizar_pedido_status(evento.pedido_id, \"confirmado\")\n        notificar_cliente(evento.pedido_id, \"Pedido confirmado!\")\n    else:\n        atualizar_pedido_status(evento.pedido_id, \"cancelado_sem_estoque\")\n        notificar_cliente(evento.pedido_id, \"Produto esgotado, pedido cancelado\")\n",[384,2576,2577,2582,2586,2591,2595,2600,2605,2609,2614,2619,2624,2629,2634,2639,2644],{"__ignoreMap":425},[694,2578,2579],{"class":696,"line":697},[694,2580,2581],{},"# ✅ CERTO: usar Saga e informar status correto\n",[694,2583,2584],{"class":696,"line":703},[694,2585,2547],{},[694,2587,2588],{"class":696,"line":709},[694,2589,2590],{},"    pedido = salvar_pedido(dados, status=\"processando\")  # não confirmado ainda\n",[694,2592,2593],{"class":696,"line":715},[694,2594,2557],{},[694,2596,2597],{"class":696,"line":721},[694,2598,2599],{},"    return {\"status\": \"processando\", \"pedido_id\": pedido.id}\n",[694,2601,2602],{"class":696,"line":727},[694,2603,2604],{},"    # Cliente sabe que está em processamento\n",[694,2606,2607],{"class":696,"line":733},[694,2608,773],{"emptyLinePlaceholder":772},[694,2610,2611],{"class":696,"line":739},[694,2612,2613],{},"# Quando estoque reserva e pagamento confirma:\n",[694,2615,2616],{"class":696,"line":745},[694,2617,2618],{},"def on_estoque_reservado(evento):\n",[694,2620,2621],{"class":696,"line":751},[694,2622,2623],{},"    if evento.sucesso:\n",[694,2625,2626],{"class":696,"line":757},[694,2627,2628],{},"        atualizar_pedido_status(evento.pedido_id, \"confirmado\")\n",[694,2630,2631],{"class":696,"line":763},[694,2632,2633],{},"        notificar_cliente(evento.pedido_id, \"Pedido confirmado!\")\n",[694,2635,2636],{"class":696,"line":769},[694,2637,2638],{},"    else:\n",[694,2640,2641],{"class":696,"line":776},[694,2642,2643],{},"        atualizar_pedido_status(evento.pedido_id, \"cancelado_sem_estoque\")\n",[694,2645,2646],{"class":696,"line":782},[694,2647,2648],{},"        notificar_cliente(evento.pedido_id, \"Produto esgotado, pedido cancelado\")\n",[155,2650,2652],{"id":2651},"erro-6-granularidade-errada-serviços-pequenos-demais-ou-grandes-demais","Erro 6: Granularidade errada (serviços pequenos demais ou grandes demais)",[85,2654,2655,2288],{},[88,2656,2281],{},[117,2658,2659,2665],{},[19,2660,2661,2664],{},[88,2662,2663],{},"Pequenos demais",": cada endpoint vira um microserviço (\"serviço de\ncriar pedido\", \"serviço de listar pedido\", \"serviço de cancelar pedido\").\n50 serviços para o que deveria ser 1. A comunicação entre eles é mais\ncomplexa que a lógica de negócio.",[19,2666,2667,2670],{},[88,2668,2669],{},"Grandes demais",": um \"microserviço\" que faz tudo do e-commerce (catálogo,\ncarrinho, checkout, pagamentos, envio). É um monolito disfarçado.",[85,2672,2673,2676,2677,2680],{},[88,2674,2675],{},"Como acertar a granularidade",": Agrupe por ",[88,2678,2679],{},"domínio de negócio"," (conceito\nde Domain-Driven Design). \"Pedidos\" é um domínio. \"Catálogo\" é outro.\n\"Pagamentos\" é outro. Dentro de cada, pode haver múltiplas operações, mas\npertencem ao mesmo serviço.",[11,2682,2684],{"id":2683},"caso-real-fintech-que-escalou-de-5k-a-2m-usuários-caso-real","Caso real: fintech que escalou de 5K a 2M usuários {#caso-real}",[85,2686,2687],{},"Uma fintech de pagamentos começou como monolito em Ruby on Rails com 5K\nusuários. Conforme cresceu, sentiu a dor:",[117,2689,2690,2696,2702],{},[19,2691,2692,2695],{},[88,2693,2694],{},"50K usuários",": deploys de 30 min (o monolito era grande), times\nbloqueando uns aos outros",[19,2697,2698,2701],{},[88,2699,2700],{},"200K usuários",": o serviço de consulta de saldo sobrecarregava todo o\nsistema (era a operação mais frequente)",[19,2703,2704,2707],{},[88,2705,2706],{},"500K usuários",": time de 20 desenvolvedores, mudanças em uma área quebravam\noutras",[85,2709,2710,2713],{},[88,2711,2712],{},"Migração gradual"," (8 meses):",[16,2715,2716,2722,2728,2734],{},[19,2717,2718,2721],{},[88,2719,2720],{},"Extraíram primeiro o serviço de consulta de saldo"," (mais trafegado)\n→ reduziu 60% da carga do monolito",[19,2723,2724,2727],{},[88,2725,2726],{},"Extraíram o serviço de notificações"," → parou de travar o processamento\nprincipal quando o SES (e-mail) tinha lentidão",[19,2729,2730,2733],{},[88,2731,2732],{},"Extraíram o serviço de anti-fraude"," → time dedicado, deploy independente,\niteração rápida em regras de risco",[19,2735,2736,2739],{},[88,2737,2738],{},"Migraram para Kubernetes"," com auto-scaling → sobreviveram a picos de\nBlack Friday sem intervenção manual",[85,2741,2742,2288],{},[88,2743,2744],{},"Resultado aos 2M usuários",[117,2746,2747,2750,2753,2756,2759,2762],{},[19,2748,2749],{},"12 microserviços (não 50 — granularidade por domínio)",[19,2751,2752],{},"Deploy de cada serviço: 3-5 minutos",[19,2754,2755],{},"Times independentes (4 squads de 5 pessoas)",[19,2757,2758],{},"Latência P99: 200ms (antes: 2-5s nos picos)",[19,2760,2761],{},"Custo de infra: $8.000\u002Fmês (antes: $12.000\u002Fmês com monolito superdimensionado)",[19,2763,2764],{},"Zero downtime em deploys",[85,2766,2767,2770],{},[88,2768,2769],{},"A lição",": Não migre tudo de uma vez. Extraia o serviço que mais dói primeiro\n(o de maior tráfego ou maior conflito entre times). Valide. Depois extraia o\npróximo. Migração incremental reduz risco e entrega valor desde o primeiro\nserviço extraído.",[2772,2773],"hr",{},[85,2775,2776,2779,2780,2784],{},[88,2777,2778],{},"Desenhando sistemas escaláveis?"," A Inicialize Tec arquiteta e implementa\nmicroserviços, desde a extração do monolito até o deploy em Kubernetes com\nobservabilidade completa. ",[22,2781,2783],{"href":2782},"\u002F#top","Conversamos sobre seu caso",".",[2786,2787,2788],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":425,"searchDepth":709,"depth":709,"links":2790},[2791,2792,2795,2799,2805,2810,2814,2819,2824,2827,2835],{"id":13,"depth":703,"text":14},{"id":82,"depth":703,"text":83,"children":2793},[2794],{"id":157,"depth":709,"text":158},{"id":260,"depth":703,"text":261,"children":2796},[2797,2798],{"id":271,"depth":709,"text":272},{"id":307,"depth":709,"text":308},{"id":351,"depth":703,"text":352,"children":2800},[2801,2802,2803,2804],{"id":355,"depth":709,"text":356},{"id":434,"depth":709,"text":435},{"id":492,"depth":709,"text":493},{"id":534,"depth":709,"text":535},{"id":598,"depth":703,"text":599,"children":2806},[2807,2808,2809],{"id":602,"depth":709,"text":603},{"id":652,"depth":709,"text":653},{"id":823,"depth":709,"text":824},{"id":988,"depth":703,"text":989,"children":2811},[2812,2813],{"id":1017,"depth":709,"text":1018},{"id":1131,"depth":709,"text":1132},{"id":1162,"depth":703,"text":1163,"children":2815},[2816,2817,2818],{"id":1166,"depth":709,"text":1167},{"id":1521,"depth":709,"text":1522},{"id":1609,"depth":709,"text":1610},{"id":1786,"depth":703,"text":1787,"children":2820},[2821,2822,2823],{"id":1809,"depth":709,"text":1810},{"id":1996,"depth":709,"text":1997},{"id":2062,"depth":709,"text":2063},{"id":2101,"depth":703,"text":2102,"children":2825},[2826],{"id":2183,"depth":709,"text":2184},{"id":2271,"depth":703,"text":2272,"children":2828},[2829,2830,2831,2832,2833,2834],{"id":2275,"depth":709,"text":2276},{"id":2308,"depth":709,"text":2309},{"id":2392,"depth":709,"text":2393},{"id":2421,"depth":709,"text":2422},{"id":2522,"depth":709,"text":2523},{"id":2651,"depth":709,"text":2652},{"id":2683,"depth":703,"text":2684},"sistemas-escalaveis","2026-08-26","Como desenhar microserviços que escalam de 1K a 10M usuários. Padrões, K8s, service mesh, saga, observabilidade e custos reais de infraestrutura.","md",[2841,2842,2843,2844,1176,2845,2846],"microserviços","arquitetura escalável","sistemas escaláveis","arquitetura de software","service mesh","API gateway",{},"\u002Fsistemas\u002Farquitetura-de-microservicos-escalaveis",{"title":5,"description":2838},"arquitetura-de-microservicos-escalaveis","sistemas\u002Farquitetura-de-microservicos-escalaveis","wcyQuvmuUWtZ18jqvq2fwBy3TKWSLFS5F4ul09_RbSI",1787796309531]