Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Microsserviços são um estilo popular de arquitetura para compilar aplicativos resilientes, altamente escalonáveis, implantáveis independentemente e capazes de evoluir rapidamente. A criação de uma arquitetura de microsserviços bem-sucedida requer uma mudança fundamental na mentalidade. Ele vai além de decompor um aplicativo em serviços menores. Você também deve repensar como os sistemas são projetados, implantados e operados.
Uma arquitetura de microsserviços consiste em uma coleção de pequenos serviços autônomos. Cada serviço é independente e deve implementar uma única funcionalidade comercial em um contexto limitado. Um contexto limitado é uma divisão natural em uma empresa e fornece um limite explícito dentro do qual um modelo de domínio existe.
O que são microsserviços?
Os microsserviços são componentes pequenos, independentes e flexívelmente acoplados que uma única pequena equipe de desenvolvedores pode escrever e manter. Cada serviço é gerenciado como uma base de código separada, o que permite que uma pequena equipe o manipule com eficiência. Como os serviços podem ser implantados de forma independente, as equipes podem atualizar os serviços existentes sem recompilar ou reimplantar todo o aplicativo. Ao contrário dos modelos tradicionais que têm uma camada de dados centralizada, os microsserviços são responsáveis por persistir seus próprios dados ou estado externo. Eles se comunicam por meio de APIs bem definidas, o que mantém as implementações internas ocultas de outros serviços. Essa arquitetura também dá suporte à programação poliglota, o que significa que os serviços não precisam compartilhar a mesma pilha de tecnologia, bibliotecas ou estruturas.
Componentes
Além dos próprios serviços, outros componentes aparecem em uma arquitetura típica de microsserviços:
Gerenciamento ou orquestração: Esse componente de gerenciamento manipula a orquestração de microsserviços. Ele agenda e implanta serviços em nós, detecta falhas, recupera falhas e habilita o dimensionamento automático com base na demanda. Uma plataforma de orquestração de contêineres como o Kubernetes normalmente fornece essa funcionalidade. Em ambientes nativos de nuvem, soluções como Aplicativos de Contêiner do Azure fornecem orquestração gerenciada e dimensionamento interno. Essas ferramentas reduzem a complexidade da implantação e a sobrecarga operacional.
Gateway de API: O gateway de API serve como o ponto de entrada para clientes. Os clientes enviam solicitações para o gateway de API em vez de chamar serviços diretamente. O gateway encaminha essas solicitações para os serviços de back-end apropriados. Ele também lida com interesses transversais, como autenticação, log e balanceamento de carga. Em arquiteturas de microsserviços nativos de nuvem, proxies de serviço leves como Envoy e Nginx dão suporte à comunicação interna de serviço a serviço. Esse tipo de tráfego interno, conhecido como tráfego leste-oeste, permite o roteamento avançado e o controle de tráfego.
Middleware orientado a mensagens: Plataformas de mensagens como o Apache Kafka e o Barramento de Serviço do Azure permitem a comunicação assíncrona em microsserviços promovendo o acoplamento flexível e dando suporte à alta escalabilidade. Eles formam a base das arquiteturas orientadas a eventos. Essa abordagem permite que os serviços reajam a eventos em tempo real e se comuniquem por meio de mensagens assíncronas.
Observabilidade: Uma estratégia de observabilidade eficaz ajuda as equipes a manter a confiabilidade do sistema e resolver problemas rapidamente. O registro em log centralizado reúne logs para dar suporte a diagnósticos mais fáceis. O monitoramento em tempo real com agentes e estruturas de monitoramento de desempenho de aplicativos, como o OpenTelemetry, fornece visibilidade sobre a integridade e o desempenho do sistema. O rastreamento distribuído rastreia solicitações entre os limites de serviço. Ele ajuda as equipes a encontrar gargalos e melhorar o desempenho.
Gerenciamento de dados: Uma arquitetura de banco de dados bem projetada dá suporte à autonomia e escalabilidade. Os microsserviços geralmente usam persistência poliglota escolhendo diferentes tipos de banco de dados, como SQL ou NoSQL, com base nas necessidades específicas de cada serviço. Essa abordagem se alinha ao DDD (design controlado pelo domínio) e à ideia de contexto limitado. Cada serviço possui seus dados e esquema. Essa propriedade reduz as dependências entre serviços e permite que os serviços evoluam de forma independente. Esse modelo descentralizado melhora a flexibilidade, o desempenho e a resiliência do sistema.
Benefícios
Agilidade: Como os microsserviços são implantados de forma independente, é mais fácil gerenciar correções de bugs e versões de recursos. Você pode atualizar um serviço sem reimplantar todo o aplicativo e reverter uma atualização se algo der errado. Em muitos aplicativos tradicionais, se você encontrar um bug em uma parte do aplicativo, ele poderá bloquear todo o processo de versão. Por exemplo, um bug pode atrasar novos recursos se você precisar integrar, testar e publicar uma correção de bug.
Equipes pequenas e focadas: Um microsserviço deve ser pequeno o suficiente para que uma única equipe de recursos possa compilar, testar e implantá-lo. Tamanhos pequenos de equipe promovem maior agilidade. Equipes grandes tendem a ser menos produtivas porque a comunicação é mais lenta, a sobrecarga de gerenciamento aumenta e a agilidade diminui.
Base de código pequena: Em um aplicativo monolítico, as dependências de código geralmente ficam emaranhadas ao longo do tempo. Adicionar um novo recurso pode exigir alterações em muitas partes da base de código. Uma arquitetura de microsserviços evita esse problema por não compartilhar armazenamentos de código ou de dados. Essa abordagem minimiza as dependências e facilita a introdução de novos recursos.
Combinação de tecnologias: As equipes podem escolher a tecnologia que melhor se adapte ao seu serviço por meio de uma combinação adequada de pilhas de tecnologia.
Isolamento de falhas: Se um microsserviço individual ficar indisponível, ele não interromperá todo o aplicativo desde que os microsserviços upstream sejam projetados para lidar com falhas corretamente. Por exemplo, você pode implementar o padrão disjuntor ou criar sua solução para que os microsserviços se comuniquem entre si usando padrões de mensagens assíncronas.
Escalabilidade: Os serviços podem ser dimensionados de forma independente. Essa abordagem permite que você expanda subsistemas que exigem mais recursos sem dimensionar todo o aplicativo. Use um orquestrador como o Kubernetes para adicionar uma densidade maior de serviços a um único host, o que permite um uso de recursos mais eficiente.
Isolamento de dados: Atualizar um esquema é mais simples em uma arquitetura de microsserviços porque apenas um microsserviço é afetado. Por outro lado, aplicativos monolíticos podem complicar as alterações de esquema, já que vários componentes geralmente interagem com os mesmos dados. Esse acesso compartilhado torna qualquer modificação potencialmente arriscada.
Desafios
Os benefícios dos microsserviços vêm com compensações. Considere os seguintes desafios antes de criar uma arquitetura de microsserviços:
Complexidade: Um aplicativo de microsserviços tem mais partes móveis do que o aplicativo monolítico equivalente. Cada serviço é mais simples, mas o sistema como um todo é mais complexo. Considere desafios como descoberta de serviço, consistência de dados, gerenciamento de transações e comunicação entre serviços ao projetar seu aplicativo.
Desenvolvimento e teste: Escrever um pequeno serviço que depende de outros serviços dependentes requer uma abordagem diferente da gravação de um aplicativo monolítico ou em camadas tradicional. As ferramentas existentes nem sempre são projetadas para funcionar com dependências de serviço. Refatorar entre limites de serviços pode ser difícil. Também é desafiador testar dependências de serviço, especialmente quando o aplicativo está evoluindo rapidamente.
Falta de governança: A abordagem descentralizada para a criação de microsserviços tem vantagens, mas também pode resultar em problemas. Você pode acabar com muitos idiomas e estruturas diferentes que tornem difícil a manutenção do aplicativo. Pode ser útil estabelecer alguns padrões para todo o projeto, sem restringir excessivamente a flexibilidade das equipes. Esse método se aplica especialmente à funcionalidade transversal, como log.
Congestionamento e latência de rede: O uso de muitos serviços granulares pequenos pode resultar em mais comunicação entre serviços. Além disso, se a cadeia de dependências de serviço ficar muito longa (o serviço A chama B, que chama C...), a latência extra pode se tornar um problema. Você precisa criar APIs com cuidado. Evite APIs excessivamente prolixas, pense em formatos de serialização e procure locais para usar padrões de comunicação assíncrona, como o Padrão de nivelamento de carga baseado em filha.
Integridade de dados: Cada microsserviço é responsável por sua própria persistência de dados. Assim, a consistência dos dados em vários serviços pode ser um desafio. Serviços diferentes persistem dados em momentos diferentes, usando tecnologia diferente e com níveis de sucesso potencialmente diferentes. Quando mais de um microsserviço está envolvido na persistência de dados novos ou alterados, é improvável que a alteração completa de dados possa ser considerada uma transação atômica, consistente, isolada e durável (ACID). Em vez disso, a técnica está mais alinhada à disponibilidade básica, estado suave e consistência eventual (BASE). Adote consistência eventual quando possível.
Gestão: Uma arquitetura de microsserviço bem-sucedida requer uma cultura de DevOps madura. Registro em log correlacionado entre serviços pode ser desafiador. Normalmente, o registro em log deve correlacionar várias chamadas de serviço para uma operação de um único usuário.
Controle de versão: As atualizações de um serviço não devem interromper os serviços que dependem dele. Vários serviços podem ser atualizados a qualquer momento, portanto, sem design cuidadoso, você pode ter problemas com compatibilidade com versões anteriores ou futuras.
Conjunto de habilidades: Os microsserviços são sistemas altamente distribuídos. Avalie cuidadosamente se a equipe tem as habilidades e a experiência para ser bem-sucedida.
Práticas recomendadas
Modele os serviços em torno de domínio da empresa. Use o DDD para identificar contextos limitados e definir limites de serviço claros. Evite criar serviços excessivamente granulares, o que pode aumentar a complexidade e reduzir o desempenho.
Descentralize tudo. Equipes individuais são responsáveis por projetar e criar serviços de ponta a ponta. Evite compartilhar esquemas de dados ou códigos.
Padronizar suas opções de tecnologia limitando o número de idiomas e estruturas que você usa. Estabeleça padrões de toda a plataforma para log, monitoramento e implantação.
O armazenamento de dados deve ser privado para o serviço que é o proprietário dos dados. Use o melhor armazenamento para cada serviço e tipo de dados.
Os serviços comunicam-se por meio de APIs bem projetadas. Evite o vazamento de detalhes da implementação. As APIs devem modelar o domínio, não a implementação interna do serviço.
Evite acoplamento entre serviços. Causas de acoplamento incluem protocolos de comunicação rígidos e esquemas de banco de dados compartilhados.
Use estruturas de mensagens para comunicação assíncrona. Adote ferramentas como MassTransit ou NServiceBus para lidar com padrões de roteamento, repetição, durabilidade e fluxo de trabalho em vez de criar lógica de mensagens personalizadas. As estruturas ajudam a reduzir a complexidade do sistema distribuído, a melhorar a confiabilidade e a evitar armadilhas comuns ao implementar microsserviços controlados por mensagens.
Melhore a segurança usando o mTLS (Segurança de Camada de Transporte mútua) para criptografia de serviço a serviço. Implemente o controle de acesso baseado em função e use gateways de API para impor políticas.
Descarregue preocupações transversais, como autenticação e encerramento de Secure Sockets Layer (SSL), para o gateway. Malhas de serviço e frameworks como o Dapr também podem ajudar com preocupações transversais comuns, como autenticação mTLS e resiliência.
Mantenha o conhecimento de domínio fora do gateway. O gateway deve tratar e rotear solicitações de cliente sem qualquer conhecimento das regras de negócios ou da lógica do domínio. Caso contrário, o gateway se tornará uma dependência e poderá causar um acoplamento entre serviços.
Os serviços devem ter um acoplamento flexível e alta coesão funcional. Funções que provavelmente mudarão juntas devem ser empacotadas e implantadas juntas. Se eles residirem em serviços separados, esses serviços acabarão sendo firmemente acoplados, pois uma alteração em um serviço requer a atualização do outro serviço. A comunicação excessiva entre dois serviços pode ser um sintoma de acoplamento forte e baixa coesão.
Use pipelines de CI/CD (integração contínua e implantação contínua) para automatizar o teste e a implantação. Implante os serviços individualmente e monitore a integridade da implantação.
Isole falhas. Use estratégias de resiliência para impedir que falhas em um serviço distribuam-se em cascata. Para obter mais informações, consulte padrões de resiliência e aplicativos confiáveis de design.
Use a engenharia do caos para testar a resiliência de sua arquitetura de microsserviço e suas dependências. Avalie e melhore como o sistema lida com falhas parciais.
Implemente o registro em log centralizado, o rastreamento distribuído (OpenTelemetry) e a coleção de métricas para garantir a observabilidade.
Antipadrões para microsserviços
Quando você projeta e implementa microsserviços, ocorrem armadilhas específicas frequentemente que podem prejudicar os benefícios desse estilo arquitetônico. Reconhecer esses antipadrões ajuda as equipes a evitar erros caros e criar sistemas mais resilientes e mantenedíveis. Evite os seguintes antipadrões:
A implementação de microsserviços sem uma compreensão profunda do domínio empresarial resulta em limites de serviço mal alinhados e prejudica os benefícios pretendidos.
A criação de eventos que dependem de eventos passados ou futuros viola o princípio das mensagens atômicas e autocontidas. Essa dependência força os consumidores a esperar e reduz a confiabilidade do sistema.
O uso de entidades de banco de dados como eventos expõe detalhes internos do serviço e, muitas vezes, falha ao transmitir a intenção de negócios correta, o que leva a integrações firmemente acopladas e pouco claras.
Evitar a duplicação de dados a todo custo é um antipadrão. O uso de padrões como visões materializadas para manter cópias locais melhora a autonomia do serviço e reduz as dependências entre serviços diferentes.
O uso de eventos genéricos força os consumidores a interpretar e filtrar mensagens. Essa abordagem adiciona complexidade desnecessária e reduz a clareza na comunicação controlada por eventos.
O compartilhamento de bibliotecas comuns ou dependências entre microsserviços cria um acoplamento rígido, o que torna as alterações arriscadas e generalizadas e vai contra o princípio dos serviços independentes.
Expor microsserviços diretamente aos consumidores resulta em acoplamento apertado, problemas de escalabilidade e riscos de segurança. O uso de um gateway de API fornece um ponto de entrada limpo, gerenciável e seguro.
Manter valores de configuração dentro de microsserviços os vincula a ambientes específicos, o que dificulta as implantações. No entanto, a externalização da configuração promove a flexibilidade e a portabilidade do ambiente.
Inserir lógica de segurança como a validação de token diretamente dentro de microsserviços complica seu código e manutenção. Como alternativa, delegar a segurança a componentes dedicados mantém os serviços focados e mais organizados.
A falha ao abstrair tarefas comuns de microsserviços resulta em código repetitivo e propenso a erros e limita a flexibilidade. Como alternativa, o uso de estruturas de abstração, como o Dapr, simplifica o desenvolvimento desassociando a lógica de negócios de questões de infraestrutura.
Criar uma arquitetura de microsserviços
Os artigos a seguir apresentam uma abordagem estruturada para projetar, criar e operar uma arquitetura de microsserviços.
Use a análise de domínio: Para evitar armadilhas comuns ao criar microsserviços, use a análise de domínio para definir seus limites de microsserviço. Efetue os seguintes passos:
- Usar análise de domínio para microsserviços de modelo.
- Usar DDD tático para projetar microsserviços.
- Identificar limites de microsserviço.
Projete os serviços: Os microsserviços exigem uma abordagem descentralizada e ágil para projetar e criar aplicativos. Para obter mais informações, consulte Criar uma arquitetura de microsserviços.
Operar em produção: Como as arquiteturas de microsserviços são distribuídas, você deve ter operações robustas para implantação e monitoramento.