Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Os microsserviços são um estilo de arquitetura popular para criar aplicações resilientes, altamente dimensionáveis, possíveis de implementar de forma independente e capazes de evoluir rapidamente. Construir uma arquitetura de microsserviços bem-sucedida requer uma mudança fundamental de 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 numa coleção de pequenos serviços autónomos. Cada serviço é autônomo e deve implementar um único recurso de negócios dentro de um contexto limitado. Um contexto delimitado é uma divisão natural dentro de uma empresa e fornece um limite explícito dentro do qual existe um modelo de domínio.
O que são os microsserviços?
Os microsserviços são componentes pequenos, independentes e com acoplamento flexível 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 de forma eficiente. Como os serviços podem ser implantados de forma independente, as equipes podem atualizar os serviços existentes sem reconstruir 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 pela persistência de 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 suporta 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 serviços em si, outros componentes aparecem em uma arquitetura típica de microsserviços:
Gestão ou orquestração: Este componente de gerenciamento lida com a orquestração de microsserviços. Ele agenda e implanta serviços através dos nós, deteta falhas, recupera de falhas e permite o dimensionamento automático com base na procura. Uma plataforma de orquestração de contêineres como o Kubernetes normalmente fornece essa funcionalidade. Em ambientes nativos da nuvem, soluções como os 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 ponto de entrada para os 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 questões transversais, como autenticação, registro em log e balanceamento de carga. Em arquiteturas de microsserviços nativas da nuvem, proxies de serviço leves como Envoy e Nginx suportam comunicação interna de serviço a serviço. Este tipo de tráfego interno, conhecido como tráfego leste-oeste, permite roteamento avançado e controle de tráfego.
Middleware orientado a mensagens: Plataformas de mensagens como Apache Kafka e Azure Service Bus permitem a comunicação assíncrona em microsserviços, promovendo acoplamento flexível e suportando alta escalabilidade. Eles formam a base de 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 centralizado reúne logs para oferecer suporte a diagnósticos mais fáceis. O monitoramento em tempo real com agentes de monitoramento de desempenho de aplicativos e estruturas como OpenTelemetry fornece visibilidade sobre a integridade e o desempenho do sistema. O rastreamento distribuído rastreia solicitações entre limites de serviço. Ajuda as equipas a encontrar gargalos e a melhorar o desempenho.
Gestão de dados: Uma arquitetura de banco de dados bem projetada suporta 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. Esta abordagem alinha-se com o design orientado por domínio (DDD) e a 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. Este 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 lançamentos 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 pode bloquear todo o processo de lançamento. Por exemplo, um bug pode paralisar novos recursos se você precisar integrar, testar e publicar uma correção de bug.
Equipas pequenas e focadas: Um microsserviço deve ser pequeno o suficiente para que uma única equipe de recursos possa criá-lo, testá-lo e implantá-lo. As equipas mais pequenas promovem uma maior agilidade. Grandes equipes 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 se tornam confusas 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 ao não compartilhar códigos ou armazenamentos 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 adapta ao seu serviço usando uma combinação de pilhas de tecnologia, conforme apropriado.
Isolamento de falhas: Se um microsserviço individual ficar indisponível, ele não interromperá todo o aplicativo, desde que todos os microsserviços upstream sejam projetados para lidar com falhas corretamente. Por exemplo, você pode implementar o padrão Disjuntor ou projetar 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 dimensionar subsistemas que exigem mais recursos sem dimensionar todo o aplicativo. Use um orquestrador como o Kubernetes para adicionar uma maior densidade de serviços em um único host, o que permite um uso de recursos mais eficiente.
Isolamento de dados: A atualização de um esquema é mais simples em uma arquitetura de microsserviços porque apenas um microsserviço é afetado. Em contraste, aplicativos monolíticos podem complicar as alterações de esquema, uma vez 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 todo o sistema como um todo é mais complexo. Certifique-se de considerar desafios como descoberta de serviços, consistência de dados, gerenciamento de transações e comunicação entre serviços ao projetar seu aplicativo.
Desenvolvimento e testes: Escrever um pequeno serviço que depende de outros serviços dependentes requer uma abordagem diferente de escrever um aplicativo monolítico tradicional ou em camadas. As ferramentas existentes nem sempre são projetadas para trabalhar com dependências de serviço. A refatoração entre limites de serviço pode ser difícil. Também é um desafio testar as dependências do serviço, especialmente quando o aplicativo está evoluindo rapidamente.
Falta de governação: A abordagem descentralizada para a construção de microsserviços tem vantagens, mas também pode resultar em problemas. Você pode acabar com tantas linguagens e estruturas diferentes que o aplicativo se torna difícil de manter. Pode ser útil implementar alguns padrões para todo o projeto, sem restringir excessivamente a flexibilidade das equipes. Este método aplica-se especialmente a funcionalidades transversais, como o registo.
Congestionamento e latência da rede: O uso de muitos serviços pequenos e granulares pode resultar em mais comunicação interserviç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 projetar APIs com cuidado. Evite APIs excessivamente verbosas, pense em formatos de serialização e procure oportunidades para usar padrões de comunicação assíncronos, como o padrãoQueue-Based Nivelamento de Carga.
Integridade dos dados: Cada microsserviço é responsável pela sua própria persistência de dados. Como resultado, a consistência de dados em vários serviços pode ser um desafio. Serviços diferentes persistem dados em momentos diferentes, usando tecnologias diferentes e com níveis potencialmente diferentes de sucesso. 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 a Basicamente Disponível, Estado Flexível, Consistência Eventual (BASE). Adote uma eventual consistência sempre que possível.
Gestão: Uma arquitetura de microsserviço bem-sucedida requer uma cultura de DevOps madura. O registro correlacionado entre serviços pode ser um desafio. Normalmente, o registo deve correlacionar várias chamadas de serviço para uma única operação do utilizador.
Controle de versão: As atualizações de um serviço não devem interromper os serviços que dependem dele. Múltiplos serviços poderiam ser atualizados num determinado momento pelo que, sem uma estrutura cuidadosa, poderia ter problemas de retrocompatibilidade ou compatibilidade com as versões seguintes.
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.
Melhores práticas
Modele serviços em torno do domínio de negócios. Use 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 construir serviços de ponta a ponta. Evite compartilhar código ou esquemas de dados.
Padronize suas opções de tecnologia limitando o número de linguagens e estruturas que você usa. Estabeleça padrões em toda a plataforma para registro, monitoramento e implantação.
O armazenamento de dados deve ser privado para o serviço que possui os dados. Use o melhor armazenamento para cada serviço e tipo de dados.
Os serviços se comunicam por meio de APIs bem projetadas. Evite vazar detalhes da implementação. As APIs devem modelar o domínio, não a implementação interna do serviço.
Evite o acoplamento entre serviços. As causas do acoplamento incluem esquemas de banco de dados compartilhados e protocolos de comunicação rígidos.
Utilize frameworks de mensagens para comunicação assíncrona. Adote ferramentas como o MassTransit ou o NServiceBus para gerir roteamentos, tentativas, durabilidade e padrões de fluxo de trabalho, em vez de construir uma lógica de mensagens personalizada. Os frameworks ajudam a reduzir a complexidade do sistema distribuído, melhoram a fiabilidade e evitam armadilhas comuns na implementação de microserviços orientados por mensagens.
Melhore a segurança usando mTLS (Transport Layer Security) mútuo 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 terminação do Secure Sockets Layer, para o gateway. Malhas de serviço e estruturas como o Dapr também podem ajudar com preocupações transversais comuns, como autenticação e resiliência de mTLS.
Mantenha o conhecimento do domínio fora do gateway. O gateway deve lidar e encaminhar solicitações de clientes sem qualquer conhecimento das regras de negócios ou da lógica do domínio. Caso contrário, o gateway se torna uma dependência e pode causar acoplamento entre serviços.
Os serviços devem ter acoplamento flexível e alta coesão funcional. As funções que provavelmente mudarão juntas devem ser empacotadas e implantadas juntas. Se residirem em serviços separados, esses serviços acabam por estar estreitamente ligados, porque uma alteração num serviço exige a atualização do outro serviço. Uma comunicação excessivamente verbosa entre dois serviços pode ser um sintoma de acoplamento forte e baixa coesão.
Utilize pipelines de integração contínua e desdobramento contínuo (CI/CD) para automatizar testes e desdobramentos. Implante serviços de forma independente e monitore o estado de saúde do lançamento.
Isole falhas. Use estratégias de resiliência para evitar que falhas em um serviço sejam cometidas em cascata. Para obter mais informações, consulte Padrões de resiliência e Projetar aplicativos confiáveis.
Use a engenharia do caos para testar a resiliência de sua arquitetura de microsserviço e suas dependências. Avalie e melhore a forma como o sistema lida com falhas parciais.
Implemente registro centralizado, rastreamento distribuído (OpenTelemetry) e coleta de métricas para garantir a observabilidade.
Antipadrões para microsserviços
Quando você projeta e implementa microsserviços, armadilhas específicas ocorrem com frequência que podem minar os benefícios desse estilo arquitetônico. Reconhecer esses antipadrões ajuda as equipes a evitar erros dispendiosos e a construir sistemas mais resilientes e fáceis de manter. Evite os seguintes antipadrões:
A implementação de microsserviços sem uma compreensão profunda do domínio de negócios resulta em limites de serviço mal alinhados e prejudica os benefícios pretendidos.
Projetar eventos que dependem de eventos passados ou futuros viola o princípio das mensagens atômicas e independentes. 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, não transmite a intenção comercial correta, o que leva a integrações fortemente acopladas e pouco claras.
Evitar a duplicação de dados a todo custo é um antipadrão. O uso de padrões como vistas materializadas para manter cópias locais melhora a autonomia do serviço e reduz as dependências entre vários serviços.
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 orientada a eventos.
O compartilhamento de bibliotecas comuns ou dependências entre microsserviços cria um acoplamento estreito, o que torna as mudanças arriscadas e generalizadas e vai contra o princípio de serviços autônomos.
Expor microsserviços diretamente aos consumidores resulta em acoplamento rígido, 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 os valores de configuração dentro dos microsserviços os associa firmemente a ambientes específicos, o que dificulta as implantações. No entanto, externalizar a configuração promove flexibilidade e portabilidade do ambiente.
Incorporar a lógica de segurança, como a validação de token, diretamente nos microsserviços, complica o código e a manutenção. Como alternativa, transferir a segurança para componentes dedicados mantém os serviços focados e mais limpos.
A falha em 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 ao dissociar a lógica de negócios das preocupações com a infraestrutura.
Crie uma arquitetura de microsserviços
Os artigos a seguir apresentam uma abordagem estruturada para projetar, construir e operar uma arquitetura de microsserviços.
Use a análise de domínio: Para evitar armadilhas comuns ao projetar microsserviços, use a análise de domínio para definir seus limites de microsserviço. Efetue os seguintes passos:
- Utilizar a análise de domínios para modelar os microsserviços.
- Utilizar o DDD tático para conceber microsserviços.
- Identificar os limites dos microsserviços.
Conceber os serviços: Os microsserviços exigem uma abordagem descentralizada e ágil para projetar e criar aplicativos. Para obter mais informações, consulte Projetar uma arquitetura de microsserviços.
Operar na produção: Como as arquiteturas de microsserviços são distribuídas, você deve ter operações robustas para implantação e monitoramento.