15 de abril de 2026
Padrões de Dados em Microserviços: Desempenho e Resiliência
Dinah Navas Elias; Everton Gomede
Resumo elaborado pela ferramenta ResumeAI, solução de inteligência artificial desenvolvida pelo Instituto Pecege voltada à síntese e redação.
O desenvolvimento de sistemas de software nas últimas décadas passou por transformações profundas, impulsionadas pela necessidade de entregas cada vez mais rápidas, escaláveis e resilientes. Dentro desse cenário, a transição de arquiteturas monolíticas para microserviços tornou-se uma tendência predominante no mercado de tecnologia da informação. Enquanto o modelo monolítico centraliza todas as funcionalidades em um único processo e base de código, o que facilita o desenvolvimento inicial e os testes de integração, ele apresenta limitações severas conforme a aplicação cresce. O acoplamento excessivo em monólitos dificulta a manutenção, torna os ciclos de implantação contínua lentos e exige que a escalabilidade horizontal seja feita de forma integral, o que eleva os custos operacionais (Newman, 2015). Em contrapartida, a arquitetura de microserviços propõe a decomposição da aplicação em um conjunto de serviços independentes e fracamente acoplados, onde cada componente é responsável por um subdomínio específico do negócio. Essa abordagem permite que equipes distintas trabalhem com autonomia, utilizem diferentes pilhas tecnológicas e escalem apenas as partes do sistema que demandam mais recursos (Nookala, 2023).
Entretanto, a adoção de microserviços introduz desafios significativos, especialmente no que diz respeito à gestão e persistência de dados. Em um ambiente distribuído, a manutenção da consistência e da integridade dos dados torna-se complexa, uma vez que a natureza ACID (atomicidade, consistência, isolamento e durabilidade) dos bancos de dados relacionais tradicionais é difícil de ser garantida entre múltiplos serviços independentes (Talaver e Vakaliuk, 2023). A estratégia de particionamento de dados impacta diretamente a performance e a resiliência do sistema. Se cada serviço possuir seu próprio banco de dados, o isolamento é máximo, mas a agregação de informações para consultas complexas exige padrões adicionais. Se o banco de dados for compartilhado, a simplicidade é mantida, mas cria-se um ponto único de falha e um acoplamento oculto que pode comprometer a agilidade da arquitetura (Munonye e Martinek, 2020).
Dentre os padrões de persistência mais discutidos na literatura técnica, destacam-se o banco de dados por serviço, o banco de dados compartilhado e a composição de API. No padrão de banco de dados por serviço, cada microserviço detém a propriedade exclusiva de seus dados, impedindo o acesso direto de outros serviços às suas tabelas. Isso promove a independência e a escalabilidade, mas dificulta a realização de consultas que envolvem dados de múltiplos domínios (Richardson, 2018). Já o padrão de banco de dados compartilhado permite que vários serviços acessem o mesmo esquema, facilitando a transição de sistemas legados e garantindo transações ACID locais, porém ao custo de um alto acoplamento (Messina et al., 2016). Por fim, o padrão de componente de integração, ou API Composition, atua como uma camada de orquestração que realiza chamadas para diversos serviços e agrega os resultados em uma única resposta, buscando equilibrar o isolamento dos dados com a necessidade de visões consolidadas (Ponce et al., 2019). O objetivo deste estudo é avaliar esses padrões por meio de uma análise comparativa rigorosa, focando em desempenho, consistência e resiliência sob condições de carga e falha.
Para a execução deste estudo, desenvolveu-se um ambiente experimental controlado simulando uma aplicação de comércio eletrônico baseada em microserviços. A infraestrutura foi montada utilizando o sistema operacional Linux e o orquestrador de containers Docker Compose, garantindo que cada serviço operasse em um ambiente isolado e reprodutível. A linguagem de programação escolhida foi o Python 3.12, utilizando o framework FastAPI devido à sua alta performance em operações assíncronas e facilidade de documentação automática. O sistema foi decomposto em quatro componentes principais: o serviço de usuários, responsável pelo cadastro e gestão de perfis; o serviço de produtos, encarregado do catálogo e controle de estoque; o serviço de pedidos, que gerencia as transações de compra; e o componente de integração, que atua como o orquestrador das consultas agregadas.
O serviço de usuários foi configurado para operar na porta 8001, o de produtos na porta 8002, o de pedidos na porta 8003 e o orquestrador na porta 8000. Cada um desses serviços implementou métodos padronizados de interface de programação de aplicações, incluindo operações de listagem, busca por identificador único, criação, atualização e remoção de registros. No caso do componente de integração, as rotas foram desenhadas especificamente para agregar dados, como a recuperação de um pedido completo contendo informações detalhadas tanto do usuário quanto dos produtos envolvidos. O banco de dados utilizado em todos os cenários foi o PostgreSQL, escolhido por sua robustez e suporte a transações complexas.
A metodologia de testes foi dividida em três fases distintas para garantir a abrangência da análise. A primeira fase consistiu em testes de sanidade, onde se validou o funcionamento básico de cada rota com uma carga mínima de um usuário virtual durante cinco minutos. O objetivo foi estabelecer uma linha de base para o tempo de resposta e garantir que não houvesse erros de implementação. A segunda fase focou em testes de carga gradual, utilizando a ferramenta Locust (Locust, 2025). O procedimento envolveu o aumento progressivo do número de usuários simultâneos, de 10 em 10, com uma taxa de crescimento de cinco usuários por segundo. Cada patamar de carga foi mantido por cinco minutos, permitindo identificar o ponto de saturação de cada arquitetura e medir métricas como requisições por segundo e latência nos percentis 50 e 95.
A terceira fase da metodologia envolveu a injeção controlada de falhas para avaliar a resiliência dos padrões. Para isso, utilizou-se a ferramenta Toxiproxy, que atua como um proxy transparente entre a aplicação e o banco de dados (Shopify, 2025). Foram simulados cenários de latência elevada, com atrasos de 60 segundos nas conexões, e falhas de conectividade total com tempos de expiração de dois segundos. Os testes de falha foram aplicados de forma sequencial e combinada nos serviços de usuários e produtos, enquanto o comportamento do serviço de pedidos e do orquestrador era monitorado. Essa abordagem permitiu observar a propagação de erros em cascata no modelo de banco compartilhado e o isolamento de falhas no modelo de banco por serviço. Antes de cada teste, todos os containers e volumes de dados foram removidos e reconstruídos para assegurar que o estado do banco de dados não influenciasse os resultados subsequentes.
Os resultados obtidos nos testes de sanidade revelaram que, em condições ideais de baixa carga, os três padrões apresentam desempenhos muito próximos. No modelo de banco de dados compartilhado, o sistema processou 199 requisições com uma latência mediana de 16 ms. As rotas de pedidos e produtos mostraram-se extremamente estáveis, enquanto a rota de usuários apresentou picos ocasionais de latência, atingindo 210 ms no percentil 95, o que indica variações pontuais no processamento de escrita. No modelo de banco de dados por serviço, o comportamento foi similar, com 197 requisições atendidas e mediana de 15 ms. Observou-se que a rota de criação de usuários teve uma dispersão maior, com percentil 95 em 60 ms, reforçando que operações de escrita em esquemas isolados podem sofrer variações dependendo da gestão de conexões do driver do banco de dados.
No padrão de componente de integração, o teste de sanidade registrou 93 requisições com uma mediana de 39 ms. O aumento no tempo de resposta em comparação aos outros modelos é justificado pela natureza das operações de agregação. Para responder a uma única consulta, o orquestrador precisa realizar múltiplas chamadas de rede para os serviços de origem, processar os dados em memória e então retornar a resposta consolidada. A rota que busca pedidos por identificador concentrou o maior volume de chamados, apresentando uma latência de 75 ms no percentil 95. Embora o desempenho seja inferior aos modelos diretos, a estabilidade foi mantida, confirmando a viabilidade do padrão para consultas complexas em ambientes distribuídos.
Ao avançar para os testes de carga gradual, as diferenças entre as arquiteturas tornaram-se evidentes. O modelo de banco de dados compartilhado demonstrou a maior capacidade bruta de processamento. Com 50 usuários simultâneos, o sistema sustentou 32,5 requisições por segundo com uma latência mediana de apenas 17 ms. Ao elevar a carga para 60 usuários, o sistema atingiu 38,6 requisições por segundo, mas começou a apresentar sinais de instabilidade, registrando as duas primeiras falhas em um universo de mais de 10 mil requisições. O percentil 95 subiu para 130 ms, indicando que a contenção de recursos no banco de dados único começa a impactar a experiência do usuário quando o volume de acessos ultrapassa o limite de conexões simultâneas configurado.
O modelo de banco de dados por serviço apresentou um limite de saturação inferior. Com 30 usuários simultâneos, o sistema manteve a estabilidade com 19,7 requisições por segundo e mediana de 18 ms. No entanto, ao atingir 40 usuários, a performance degradou-se de forma mais acentuada que no modelo compartilhado. Foram registradas duas falhas em 7836 requisições, e a taxa de processamento estabilizou em 26,1 requisições por segundo. As rotas de escrita de pedidos e usuários foram as mais afetadas, com latências subindo para 120 ms e 63 ms respectivamente no percentil 95. Esse comportamento sugere que a sobrecarga de gerenciar múltiplos bancos de dados independentes e a latência de rede adicional entre os serviços limitam a escalabilidade vertical em comparação à eficiência de um banco centralizado que utiliza transações locais.
No cenário de carga para o componente de integração, o sistema suportou 30 usuários simultâneos com uma taxa de 7,99 requisições por segundo e latência mediana de 40 ms. Ao subir para 40 usuários, o sistema processou 11 requisições por segundo, mas apresentou uma falha e um aumento na latência para 79 ms no percentil 95. A análise detalhada mostrou que as rotas de agregação de pedidos por usuário foram as mais lentas, evidenciando que o custo de orquestração cresce de forma não linear com o aumento da carga. Cada requisição adicional ao orquestrador gera um efeito multiplicador de chamadas internas, o que consome rapidamente os recursos de rede e os slots de processamento do framework FastAPI.
A análise de resiliência por meio da injeção de falhas trouxe as conclusões mais críticas deste estudo. No Teste 1, que simulou latência de 60 segundos nos serviços de usuários e produtos, o modelo de banco de dados compartilhado exibiu uma resiliência inesperada. O sistema processou 8845 requisições com apenas uma falha, mantendo uma mediana de 18 ms. Isso ocorreu porque, embora as interfaces de programação de aplicações estivessem lentas, os serviços internos continuaram acessando o banco de dados de forma direta e eficiente. No entanto, essa configuração mascara problemas de infraestrutura que, em um cenário real, poderiam levar ao esgotamento de threads no servidor web.
Em contraste, o modelo de banco de dados por serviço sofreu severamente no Teste 1. A injeção de latência resultou em uma taxa de falha de 17%, com 81 erros em 488 requisições. As rotas de leitura foram as mais prejudicadas, com latências medianas saltando para 30 mil milissegundos. Como cada serviço depende de sua própria conexão e a latência foi injetada na camada de rede do banco, o tempo de espera excedeu os limites de tempo de expiração das requisições HTTP. O componente de integração apresentou o pior desempenho nesse cenário, com 90% das requisições resultando em erro e latências fixas em 10 mil milissegundos, demonstrando que falhas em serviços de base inviabilizam completamente a camada de orquestração.
O Teste 2, que simulou falhas de conexão total, reforçou a robustez do banco compartilhado em termos de disponibilidade, processando mais de 9700 requisições com apenas três falhas. Contudo, o Teste 3, focado em falhas no serviço de pedidos, revelou o perigo do acoplamento. No modelo compartilhado, a falha em um serviço propagou-se rapidamente, gerando erros em 86% das requisições totais. O sistema entrou em um estado de degradação sistêmica, onde a indisponibilidade de um componente afetou a integridade das transações dos demais. Já no modelo de banco de dados por serviço, a falha permaneceu isolada. Embora o serviço de pedidos tenha apresentado 95% de erro, os serviços de usuários e produtos continuaram operando com 100% de sucesso e latências baixas (14 a 18 ms). Isso comprova que o isolamento de dados é a estratégia mais eficaz para garantir a disponibilidade parcial do sistema, impedindo que um problema em um subdomínio derrube toda a plataforma.
A discussão dos resultados permite inferir que não existe um padrão universalmente superior, mas sim compensações que devem ser avaliadas conforme os requisitos do projeto. O banco de dados compartilhado oferece uma performance superior em termos de vazão de requisições, sendo aproximadamente 43% mais eficiente que os modelos distribuídos em cenários de alta carga sem falhas. Sua implementação é mais simples e permite manter a consistência transacional sem esforço adicional de desenvolvimento (Kalske et al., 2018). No entanto, sua vulnerabilidade a falhas em cascata e o acoplamento de esquemas representam riscos significativos para a evolução do software a longo prazo.
O padrão de banco de dados por serviço, embora apresente uma sobrecarga de latência e exija uma gestão mais complexa de infraestrutura, cumpre a promessa de resiliência da arquitetura de microserviços. A capacidade de manter partes do sistema operacionais enquanto outras estão em falha é um requisito essencial para aplicações de missão crítica. O uso de componentes de integração como o API Composer facilita a experiência do usuário final ao consolidar dados, mas deve ser utilizado com cautela devido ao seu impacto no tempo de resposta e à sua dependência direta da saúde de todos os serviços subordinados. Para mitigar esses problemas, a literatura sugere a implementação de padrões complementares, como o uso de caches distribuídos ou a segregação de responsabilidade de comando e consulta, que poderiam aliviar a carga sobre o orquestrador (Richardson, 2018).
As limitações deste estudo incluem o uso de uma aplicação fictícia com regras de negócio simplificadas e a execução em um único nó de computação, o que não captura totalmente as latências de rede de um ambiente de nuvem distribuído geograficamente. Pesquisas futuras poderiam explorar o comportamento desses padrões em arquiteturas baseadas em eventos, onde a consistência eventual substitui a consistência imediata, e avaliar o impacto de ferramentas de malha de serviço na gestão de falhas e retentativas automáticas. Além disso, a análise de custos operacionais e de armazenamento para manter múltiplos bancos de dados independentes versus um banco centralizado traria uma dimensão econômica importante para a tomada de decisão arquitetural.
Conclui-se que o objetivo foi atingido, uma vez que a análise comparativa demonstrou que o padrão de banco de dados compartilhado é superior em desempenho bruto e simplicidade, enquanto o padrão de banco de dados por serviço é fundamental para garantir o isolamento de falhas e a resiliência sistêmica. O componente de integração mostrou-se uma ferramenta útil para a agregação de dados, apesar de introduzir latência adicional. A escolha entre os padrões deve ser guiada pela priorização entre velocidade de processamento e tolerância a falhas, sendo recomendado o uso de bancos isolados para sistemas que buscam alta disponibilidade e o uso de bancos compartilhados apenas em fases iniciais de migração ou em sistemas com baixa complexidade de integração.
Referências Bibliográficas:
Kalske, M.; Mäkitalo, N.; Mikkonen, T. 2018. Challenges When Moving from Monolith to Microservice Architecture. In: International Conference on Web Engineering Workshops, 2017, Roma, Itália. Anais… p. 3-8.
Locust. n.d. Locust. Disponível em: https://docs.locust.io. Acesso em: 14 set. 2025.
Messina, A.; Rizzo, R.; Storniolo, P.; Urso, A. 2016. A simplified database pattern for the microservice architecture. In: DBKDA 2016, The Eighth International Conference on Advances in Databases, Knowledge, and Data Applications, 2016, Lisboa, Portugal. Anais… p. 35-42.
Munonye, K.; Martinek, P. 2020. Evaluation of Data Storage Patterns in Microservices Archicture. In: Simpósio Internacional de Engenharia de Sistemas (SoSE), 2020, Budapeste, Hungria. Anais… p. 373-380.
Newman, S. 2015. Building Microservices: Designing Fine-Grained Systems. O’Reilly Media, Sebastopol, CA, USA.
Nookala, G. 2023. Microservices and data architecture: Aligning scalability with data flow. Research Workx International Journal of Digital Innovation, 4(1): 19-36.
Ponce, F.; Márquez, G.; Astudillo, H. 2019. Migrating from monolithic architecture to microservices: A Rapid Review. In: 38th International Conference of the Chilean Computer Science Society (SCCC), 2019, Conceição, Chile. Anais… p. 1-7.
Richardson, C. 2018. Microservices Patterns: With Examples in Java. Manning, Shelter Island, NY, USA.
Shopify. n.d. Toxiproxy. Disponível em: https://github.com/Shopify/toxiproxy. Acesso em: 15 set. 2025.
Talaver, O.V.; Vakaliuk, T.A. 2023. Reliable distributed systems: review of modern approaches. Journal of Edge Computing, 2(1): 84-101.
Resumo executivo oriundo de Trabalho de Conclusão de Curso da Especialização em Engenharia de Software do MBA USP/Esalq
Para saber mais sobre o curso, clique aqui e acesse a plataforma MBX Academy




























